최대 fd 값은 (윈도우에선 이방법 안통함 -_-) 걍 소켓은 integer 형이죠? 그리고 그 소켓중에서 가장 큰 값이 최대 fd 값입니다.
책에는 이렇게 설명되어 있습니다.
"select에 대한 요청은 집합 {1,4,5} 에 있는 화일 지정번호가 읽을 준비가 되어 있는지 또는 집합 {2,7}에 있는 화일 지정번호가 출력할 준비가 되어있는지, 또는 집합 {1,4}에 있는 화일 지정 번호가 미결 예외조건 (exeptional condition pending) 을 갖고 있는지를 우리에게 말해줄 수 있다. 추가적으로 우리는 알맹이에게 아래와 같은 사항들을 요청할 수 있다."
해석 : (이책은 원서는 그냥 그런데 해석본이 완전 엉망임 푸하하) 우선 알맹이는 커널(Kernel) 을 뜻합니다. 한마디로 select 함수를 호출해 해당 fd (소켓 포함) 에서 읽어올 수 있나 출력 할 수 있나 예외가 있는가를 알아올 수 있다는 거죠. -.-;
------------- 첫번째 사용법 ------------- o 지정번호들을 조사한 후에 즉시 돌려주시오. 이것은 응답조사이다. 이것을 위해 timeout 독립변수는 timeval 구조를 가리키고 있어야 한다. 시간 측정의 값은 0 이어야 한다. (시간 측정기의 값은 구조에서 규정한 seconds 또는 microseconds)
- 해석 : 여기서 '지정번호들'은 최대 fd 값의 아래번호를 가진 fd 가 되겠습니다. 그리고 시간 측정의 값은 0 이어야 한다 이말은 select() 함수의 맨 마지막 인자 struct timeval 을 0 으로 모두 만들어서 넣어야 원하는 방향으로 만들어 진다는 겁니다.
- 이렇게 하려면? fd_set input, output, exc; struct timeval nulltime;
nulltime.tv_sec = 0; nulltime.tv_usec = 0;
FD_ZERO(&input); FD_ZERO(&output); FD_ZERO(&exc);
FD_SET(접속을 받고 있는 fd, &input); // 접속을 받고 있는 fd 란 서버가 띄워진 포트에 물린 소켓의 번호를 // 뜻합니다.
// 모든 디스크립터에 input, output, exc 를 셋팅한다. 루프 { FD_SET(fd, &input); FD_SET(fd, &output); FD_SET(fd, &exc); }
// 예외를 검사 루프 { if (FD_ISSET(이번fd, &exc)) 예외 발생 소켓을 끊어준다. }
// 읽기 가능 검사 루프 { if (FD_ISSET(이번fd, &input)) 읽기 가능 소켓에서 읽어준다. }
// 쓰기 가능 검사 루프 { if (FD_ISSET(이번fd, &output)) 쓰기 가능 소켓에 쓸 내용이 있다면 써준다. }
위와 같은 방식으로 사용하면 되겠습니다. 윈도우에선 메세지를 받아 처리한다는 분들도 계시는데 써보지 않아 둘중 어느 것이 속도면에서 나을지는 잘 모르겠습니다. (처리는 훨씬 편하겠군. -_-)
- 필요한 곳은? 제일 중요 부분이라 할 수 있는 여러 소캣에서의 읽기가능/쓰기가능/예외를 얻어올 때. 한마디로 서버의 중추적인 역할을 할 수 있게 할 때.
------------- 두번째 사용법 ------------- o 지정된 지정번호들중의 하나가 I/O 준비가 될 때 돌려 주되 고정된 시간 이상을 기다리지 마시오. 이것을 위해 timeout 독립변수는 timeval 구조를 가리키고 있어야 하며 이 값은 기다릴 시간이며 0 이 아니어야 한다. (시간 측정기의 값은 구조에서 규정된 seconds 또는 microseconds)
- 해석: (이미 설명한 부분을 건너 뛰도록 하겠습니다.) 별거 없습니다. 그냥 timeval 구조내에 있는 시간만큼 프로세스를 잠재운다. 입니다. -_-;
- 필요한 곳은? 프레임 동기화에 쓸 수 있겠습니다. sleep 같은 무식하고 조금밖에 못쉬는 함수보단 nanosleep() 이나, usleep() 혹은 이 select() 함수를 이용해 쉬게 하는 방법도 괜찮은 방법. 윈도우에선 Sleep() 함수로 다음과 같은 방법으로 잠재울 수 있겠습니다.
------------- 세번째 사용법 ------------- o 지정된 지정번호들중의 하나가 I/O 준비가 될때까지 무조건 기다리다 준비가 되었을때 돌려 주시오. 이것을 위해 timeout 독립변수는 NULL 이어야 한다. 이러한 기다림은 신호에 의해 일시 중단될 수 있다.
- 해석: 최대 fd 값보다 적은 값을 가진 fd 들의 입력/출력/예외가 생길 때 까지 프로세스를 잠재우다 생기면 함수를 리턴 시킵니다. 이렇게 하려면 select() 함수의 마지막 인자는 NULL 로 주어야 합니다. 그리고 시그널에 의해 리턴될 수도 있습니다.