select함수의 writefds

게임 서버 프로그래밍/네트워크 잡것들

2020. 4. 16. 02:10

책의 예제나 구글 검색을 통해서는 writefds가 정확히 무얼 하는녀석인지 가늠하기가 힘들었다.

 정의는 '블로킹되지 않고 데이터의 전송이 가능한 소켓은 무엇인가?'와 대응된다.

 

이것에 대해서 정확한 답변을 얻어내기 위해 이번에도 throwbug의 힘을 빌렸다! (게임코디 사랑해요)

답변을 그대로 옮겨보자면

 

더보기

writeset 의 목적은  지금 send 함수가 가능한가? 를 확인 하는 용도 입니다.  좀더 정확한 의미로는  송신버퍼에 여유가 있는가? 를 확인 해준다고 보시면 됩니다.

블럭,논블럭 소켓 여부를 확인 하는것은 아닙니다.

블럭소켓에서 select 의  writeset 을 확인 후 send 를 호출 한다면 블럭되지 않게 send 를 할 수 있겠고요,

논블럭소켓 대상으로 select 의 writeset 확인 후 send 를 호출하면  wouldblock 에러가 발생하지 않게 send 를 할 수 있습니다.

 

정말 답변이 명확해서 추가로 설명을 덧붙일 말도없다. 

nhn-next 깃헙 자료에서는 writeset과 readset을 같은 변수를 받아서 사용했었는데, 생각해보면 당연한 것이었다.

//....

FD_SET(m_servSock,&m_readfds);
// ...

auto readfds,writefds;
readfds = m_readfds;
writefds = m_readfds;

auto ret = select(0,&readfds,&writefds,nullptr,nullptr);

전체적인 select 로직을 따져보면

 

1. server 소켓 하나를 셋에 넣는다.

2. select를 통해 복사된 셋에 send/recv 가능여부를 확인한다.

3. client 소켓들을 accept로 받아들인 후 셋에 넣는다. (server 소켓이 들어간 셋과 같음)

 

1번을 제외하고 루프를 돌려주면 끝. 

어떤 책에서는 fd들을 vector 형식에 넣어주기도하고, 또 어떤 책에서는 client들을 구조체형식으로 만든 후 적절한 자료구조에 넣어주기도 하더라. (나는 후자의 방식으로 포폴을 짜는중이다.)

후자의 방식을 쓰면 쓸데없이 fd가 server인지 cli인지 구분하는 로직을 짜지 않아도 된다. 

 

fd_isset와 반복문을 통해서 해당 클라이언트가 set되어있는지 확인하면서 send/recv 과정을 이어나가면 된다.

 

 

 

'게임 서버 프로그래밍 > 네트워크 잡것들' 카테고리의 다른 글

용량 ㅜ  (0) 2021.10.19
mysqld port 문제..  (0) 2021.10.11
Centos7 + nginx + php-fpm 설정  (0) 2021.10.04
Packet Generator에 대한 고찰  (0) 2020.11.08
UDP와 Select()  (0) 2020.02.27