본문 바로가기

Management/Linux

select / FD_SET / FD_Zero / FD_IsSet 레퍼런스

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)
    모든 소켓 기술자를 세크에서 제거합니다.


FD_SET

typedef struct fd_set {
        u_int       fd_count;                     /* how many are SET? */
        SOCKET  fd_array[FD_SETSIZE]; /* an array of SOCKETs */
} fd_set;

Element Usage
fd_count 설정하는 소켓의 번호
fd_array 설정된 소켓의 배열


FD_Zero

Clear all file descriptors in set

Declaration

Source position: oldlinux.pp line 1594

procedure FD_Zero(

  var fds: fdSet

);

Description

FD_ZERO clears all the filedescriptors in the file descriptor set fds.

For an example, see Select.

Errors

None.


FD_Clr

Clears a filedescriptor in a set

Declaration

Source position: oldlinux.pp line 1595

procedure FD_Clr(

  fd: LongInt;

  var fds: fdSet

);

Description

FD_Clr clears file descriptor fd in filedescriptor set fds.

For an example, see Select.

Errors

None.




FD_IsSet

Check whether a filedescriptor is set

Declaration

Source position: oldlinux.pp line 1597

function FD_IsSet(

  fd: LongInt;

  var fds: fdSet

):Boolean;

Description

FD_Set Checks whether file descriptor fd in filedescriptor set fds is set.

For an example, see Select.

Errors

None.