select
select 함수는 한개 또는 그 이상의 소켓 상태를 결정하고, 동기 입출력을 수행 하기위해 필요할 경우 대기 하는 함수입니다.
int select (
int nfds,
fd_set FAR * readfds,
fd_set FAR * writefds,
fd_set FAR * exceptfds,
const struct timeval FAR * timeout
);
Parameters
nfds
[입력] 버클리 소켓과 호환되는 소켓을 제외 하고는 이 매개변수는 무시됩니다. 버클리 소켓에서 이 매개변수는 I/O 변화를 감지 할 총 소켓의 갯수+1 의 값을 지정하는 용도로 사용합니다.
readfds
[입/출력] 읽기상태의 변화를 감지할 소켓을 지정합니다.
writefds
[입/출력] 쓰기상태의 변화를 감지할 소켓을 지정합니다.
exceptfds
[입/출력] 예외상태 변화를 감지할 소켓을 지정합니다.
timeout
[입력] select 함수가 기다리기 위한 시간입니다. NULL 일경우 지정한 I/O변화가 발생했을 때까지 계속 기다립니다.
Remarks
select 함수는 한개 또는 그 이상의 소켓상태(I/O의 발생유무 상태)를 결정하는데 사용됩니다. FD_SET 구조체의 타입의 인자인 readfds, writefds, exceptfds는 각각 읽기, 쓰기, 예외상황 발생과 같은 I/O변화가 발생 했을 때 이를 감지할 대상이 되는 소켓들을 지정하는 배열형 구조체 입니다. 즉, 이 세가지 구조체를 통하여 어떤 소켓에서 어떤 I/O 변화 발생을 감지할지를 선택하여 지정할 수 있습니다. FD_SET 구조체를 처리하기 위해서 일련의 매크로들이 제공되게 됩니다. 이러한 매크로들은 버클리 소켓과 호환성이 있습니다. 하지만, 내부적인 표현 방법은 근본적으로 다릅니다.
readfds 매개변수에는 "입력받을 수 있는 상태"(readability)와 같은 입력(Input)에 대해 변화가 발생 했을때 감지할 대상이 되는 소켓들을 지정합니다. 예를들어 소켓이 리슨 상태라면, 상대방의 접속의 요청에 대한 감지나, 수신큐에 데이터가 수신되었을 때 이를 감지 할 수 있게 됩니다. 어플리케이션은 이런 상황이 감지 되었을때 접속을 허용 하거나 데이터를 수신할 수 있습니다.
writefds 매개변수에는 "출력 할 수 있는 상태"(writability)와 같은 출력(Output)에 대해 변화가 발생 했을때 감지할 대상이 되는 소켓들을 지정합니다. 예를들어 소켓이 connect 함수를 처리하고 있으며, 소켓이 성공적으로 접속이 완료되었을때 다른 데이터를 송신 할 수 있다 라는 변화의 감지나, sendto, WSASendTo 등의 함수가 성공적으로 수행 될수 있을때가 언제인지 감지 할 수 있게 됩니다. 어플리케이션은 이런 상황이 감지 되었을때 소켓에 대한 다른 처리를 하거나, 데이터를 송신 할 수 있습니다.
exceptfds 매개변수는 out-of-band 데이터의 감지를 위해서, 또는 예외적인 에러 상황을 감지하기 위해서 사용됩니다.
readfds, writefds, 또는 exceptfds 매개변수중 두개는 NULL을 가질 수 있습니다. 하지만, 적어도 한개는 NULL 이면 않됩니다. 또한 NULL이 아닌 FD_SET 구조체는 적어도 한개의 소켓을 가지고 있어야 한다는 점을 명심하세요.
windsock(2).h 헤더 파일에는 소켓기술자 세트(ex. FD_SET)를 처리하기 위해서 4가지 종류의 매크로를 정의 해 놓고 있습니다. FD_SETSIZE 값은 소켓기술자 세트(ex. FD_SET)에 들어갈 수 있는 소켓 기술자의 최대 갯수를 결정하는 수치입니다. (FD_SETSIZE 의 기본치는 64입니다. 이값은 winsock(2).h 헤더파일에서 FD_SETSIZE 가 정의 되어 있지 않을 경우 FD_SETSIZE를 64로 정의 하므로 이 헤더파일을 인클루드 하기전에 다른 값을 FD_SETSIZE에 정의해서 변경 할 수 있습니다.)
내부적으로, 소켓기술자 세트로 사용되는 FD_SET 구조체 안에 있는 소켓핸들은 버클리 유닉스와 같은 비트 플래그로 표현되지 않습니다(버클리 유닉스 에서는 세트되어 있다는 것을 1로 그렇지 않은 것을 0으로 표현하죠.). 이 소켓핸들 데이터 표현법은 확실히 정의된 것이 아닙니다. 이렇게 확실히 정의 해 놓지 않은 이유는, 다른 소켓환경 사이에서 소프트웨어를 포팅 하려할 때, 많은 확장성을 제공해 주기 위함입니다. FD_SET 구조체를 처리하는 매크로는 다음과 같습니다.
FD_CLR(s, *set)
지정된 소켓 기술자(descriptor)를 세트에서 제거 합니다.
FD_ISSET(s, *set)
지정된 소켓 기술자가 세트에 있을 경우 0이 아닌값을 반환하고, 없을 경우 0을 반환합니다.
FD_SET(s, *set)
지정된 소켓 기술자를 세트에 추가 합니다.
FD_ZERO(*set)
모든 소켓 기술자를 세크에서 제거합니다.
timeout(TIMEVAL) 매개변수가 NULL 일 경우 select 함수는 하나 이상의 소켓이 읽기 가능한 것이 되거나, 쓰기 가능한 것이 되거나, 에러 상황이 발생할 때까지 무제한으로 대기합니다. NULL이 아니라면, select 함수는 하나 이상의 소켓이 지정된 기준(일기, 쓰기, 예외)을 만나거나 timeout 값에 일를 때까지 대기합니다. timeout 매개변수가 {0,0}으로 초기화 되어있다면, select 함수는 바로 리턴될 것입니다. 이렇게 초기화 하는 것은 선택된 소켓의 상태를 "poll" 하기 위해서 사용 하는 방법입니다.
Note : select 함수는 WSAAsyncSelect 나 WSAEventSelect 함수로 등록된 소켓 이벤트에 대해서 아무런 영향을 미치지 않습니다.
Return Values
select 함수는 FD_SET 구조체에 포함되어 지정된 I/O에 준비하고 있는 소켓 핸들의 총 갯수를 반환합니다. 지정된 타임아웃 시간을 초과하면, 0을 반환하고 에러가 발생 한 경우 SOCKET_ERROR을 반환하고, WSAGetLastError 함수로 특정한 에러코드를 얻을 수 있습니다.
Error Codes
WSANOTINITIALISED |
이 함수를 사용하기 전에 성공적인 WSAStartup 함수의 호출이 없었습니다. |
WSAEFAULT |
윈속이 내부적인 동작을 위한 리소스를 할당받지 못했거나, readfds, writefds, exceptfds 또는 timeval 매개변수가 잘못된 값입니다. |
WSAENETDOWN |
네트웍 서브 시스템에 에러가 발생했습니다. |
WSAEINVAL |
timeout 값이 잘못넘겨졌거나, 소켓 기술자 세트를 넘겨주는 3개의 매개변수가 모두 NULL 입니다. |
WSAEINTR |
블록킹 호출이 WSACancelBlockingCall 함수에서 취소되었습니다. |
WSAEINPROGRESS |
블럭킹 윈속 v1.1 이 현재 진행 중이거나, 서비스 프로바이더가 콜백 함수를 여전히 처리하고 있습니다. |
WSAENOTSOCK |
소켓 기술자 세트 중의 하나가 소켓이 아닌 항목을 포함하고 있습니다. |
QuickInfo
Windows NT : 사용가능
Windows : 사용가능
Windows CE : 버젼 1.0 그리고 그이후의 버젼에서 사용가능
Header :
Win16/32 : winsock.h
Win32-II : winsock2.h
Import Library :
Win16 : winsock.lib
Win32 : wsock32.lib
Win32-II : ws2_32.lib
See Also
overview, accept, connect, recv, recvfrom, send, WSAAsyncSelect, WSAEventSelect