2009. 7. 9. 11:27

[소켓프로그래밍] WSAAsyncSelect

WSAAsyncSelect

WSAAsyncSelect 함수는 지정된 소켓에 대해서 특정한 네트웍 이벤트에 대한 윈도즈 통지 메시지를 받을 것인지 않받을 것인지 설정하는 함수입니다.    - 좀 양이 많네요^^ 그래두 중요한 부분이니까 꼭 숙지 하도록 해요.

int WSAAsyncSelect (
            SOCKET   
s,
            HWND   
hWnd,
            unsigned int   
wMsg,
            long   
lEvent
);

 

Parameters

s
[입력] 이벤트 통지를 설정할 대상 소켓 기술자

hWnd
[입력] 네트웍 이벤트가 발생 했을 때 메시지를 수신할 윈도즈 핸들

wMsg
[입력] 네트웍 이벤트가 발생했을 때 수신될 메시지

lEvent
[입력] 어플리케이션이 수신할 네트웍 이벤트의 비트조합

 

Remarks

WSAAsyncSelect 함수는 WS2_32.DLL 이 IEvent 매개변수에 의해 지정된 네트웍 이벤트가 발생했을대 마다 hWnd 윈도우로 메시지를 보내야 할 때 사용됩니다. 보내야 하는 메시지는 wMsg 매개변수로 지정한 메시지가 되고, 통지받는 대상 소켓은 s 매개변수에 의해서 지정된 소켓입니다.

WSAAsyncSelect 함수는 IEvent 값에 개의치 않고, 소켓 s 를 비동기 모드로 자동적으로 설정합니다. 동기모드에서 비동기 모드로 설정하는 방법에 대해 알고 싶으면, ioctlsocket 함수를 참조하도록 하세요.

IEvent 매개변수는 아래 리스트에 보이는 값들을 OR 비트연산 해서 구성된 값으로 이루어 집니다.

Value Meaning
FD_READ 데이터 수신 통지메시지를 수신 하려할때.
FD_WRITE 데이터 전송이 준비가 되었다는 통지메시지를 수신하려 할 때
FD_OOB out-of-band 데이터가 수신되었다는 통지메시지를 수신하려 할때
FD_ACCEPT 접속 요구가 들어왔다는 통지메시지를 수신하려 할때
FD_CONNECT 접속이나, multi-point join 작업이 완료되었다는 통지메시지를 수신하려 할 때
FD_CLOSE 연결된 상대방 소켓이 종료되었다는 통지메시지를 수신하려 할 때
FD_QOS Socket Quality of Service(QOS)가 변경되었다는 메시지를 수신하려 할 때
FD_GROUP_QOS Socket Group Quality of Service(QOS)가 변경되었다는 메시지를 수신하려 할 때
FD_ROUTING
_INTERFACE_CHANGE
지정된 목적지(들)에 대해서 경로배정 인터페이스가 변경되었다는 메시지를
수신하려 할 때.
FD_ADDRESS_LIST
_CHANGE
소켓의 프로토콜 집합에 대한 로컬 어드레스 리스트가 변경되었다는 메시지를
수신하려 할 때.

간단한 사용법을 한번 알아 볼까요? 데이터의 수신과 송신 통지 메시지를 수신하기 위해서는 FD_READ 그리고, FD_WRITE를 비트연산자로 합쳐서 WSAAsyncSelect 함수를 호출하게 됩니다. 아래와 같이 말이죠.

rc = WSAAsyncSelect(s, hWnd, wMsg, FD_READ|FD_WRITE);

WSAAsyncSelect 함수를 지정된 IEvent 를 가지고 호출하게 되면, 이전에 동일한 소켓에 대해서 WSAAsyncSelect 함수나 WSAEventSelect 함수로 설정되어 있던 메시지 이벤트는 무시됩니다. 새로 설정된 메시지 이벤트가 영향력을 미치게 되는 것이죠. 아래의 코드에서는 s 소켓에 대해서 wMsg2 메시지로 FD_WRITE 이벤트만이 발생하게 됩니다.

rc = WSAAsyncSelect(s, hWnd, wMsg1, FD_READ);
rc = WSAAsyncSelect(s, hWnd, wMsg2, FD_WRITE);

소켓에 대해 설정되어있는 모든 네트웍 통지메세지를 앞으로 수신받지 않으려면, IEvent 를 0으로 셋팅하면, 됩니다.

rc = WSAAsyncSelect(s, hWnd, 0, 0);

WSAAsyncSelect 함수가 소켓에 대한 이벤트 메시지를 바로 비활성화 시킬지라도, 메시지가 어플리케이션의 메시지 큐에서 대기하도록 하는 것은 가능합니다. 따라서 어플리케이션은 취소작업후에 네트웍 이벤트 메시지를 수신받기위해 준비해야 합니다. closesocket 함수로 소켓을 닫는겨우 역시 WSAAsyncSelect 메시지 전송을 취소 하지만, 큐에 남아있던 메시지는 없어지지 않고 여전히 남아있게 됩니다.

accept 함수로 생성된 소켓은 이 소켓을 접속허용 하는데 사용되었던 리슨소켓(listen socket)과 같은 속성을 가지게 됩니다. 그 결과로 리슨소켓에 WSAAsyncSelect 로 셋팅되었던 이벤트는 접속허용된 소켓에 그대로 적용됩니다.  한 예로, 리슨소켓이 FD_ACCEPT, FD_READ, 그리고 FD_WRITE 이벤트를 가지고 있다면, 이 리슨소켓으로 접속허용된 소켓 또한 역시 FD_ACCEPT, FD_READ, 그리고 FD_WRITE 속성을 가지게 된다는 거져. 만약 새로 접속허용된 소켓에 대해서 다른 wMsg 와 이벤트를 적용시키고 싶다면, WSAAsyncSelect 함수를 사용해서 새로운 적절한 이벤트 정보를 다시 설정해야 합니다.

등록된 네트웍 이벤트가 지정된 소켓 s 에 대해서 발생했을 때, 어플리케이션 윈도우 hWnd wMsg 메시지를 수신받게 됩니다. wParam 매개변수는 네트웍 이벤트가 발생한 소켓을 의미합니다. lParam의 하위 16비트는 발생된 네트웍 이벤트를 의미하고, lParam의 상위 16비트는 특정한 에러코드를 의미합니다. 에러코드는 WINSOCK(2).H에 정의된 에러코드 입니다.

이벤트 통지 메시지를 사용하는 방법에서, WSAGetLastError 함수는 에러값을 체크하는데 사용할 수 없습니다. 왜냐믄, WSAGetLastError 함수의 리턴값이 lParam의 상위 16비트와 다를 수 있기 때문입니다.

에러코드와 이벤트코드는 WSAGETSELECTERROR와 WSAGETSELECTEVENT 매크로를 사용해서 lParam으로부터 뽑아낼 수 있습니다. 이 매크로는 WINSOCK(2).H에 정의되어 있습니다.

#define WSAGETSELECTERROR(lParam) HIWORD(lParam)
#define WSAGETSELECTEVENT(lParam) LOWORD(lParam)

이러한 매크로를 사용하면, 코드의 이식성이 좋아진다고 합니다.

사용가능한 네트웍 이벤트 코드를 아래에 리스팅 했습니다. 참고 하세요.

Value Meaning
FD_READ 데이터를 수신 할 수 있는 상태가 되었당.
FD_WRITE 데이터를 전송 할 수 있는 상태가 되었당.
FD_OOB out-of-band 데이터를 수신할 수 있는 상태가 되었당.
FD_ACCEPT 새로운 접속 요구를 허용할 준비가 되었당.
FD_CONNECT 접속 또는 multi-point join 연산이 완료되었당.
FD_CLOSE 연결된 상태방 소켓이 종료 했당.
FD_QOS Socket Quality Of Service 가 변경되었당.
FD_GROUP_QOS Socket Group Quality of Service(QOS)가 변경되었당
FD_ROUTING
_INTERFACE_CHANGE
지정된 목적지(들)에 대해서 경로배정 인터페이스가 변경되었당.
FD_ADDRESS_LIST
_CHANGE
소켓의 프로토콜 집합에 대한 로컬 어드레스 리스트가 변경되었당.

WSAAsyncSelect 함수는 데이터 전송/수신 연산(send 또는 recv) 을 성공적으로 할 수 있을 때를 결정하는데 주로 사용됩니다. 이렇게 사용되는 경우, 튼튼한 어플리케이션을 만들려면, WSAEWOULDBLOCK이 발생될 수 있는 상황에 대해서 철저한 준비를 해야합니다. 한 예로 아래와 같은 상황이 일어 날 수도 있습니다.

1. 데이터가 소켓 s 에 도착했습니다... 삐리비리빅~
    이때 윈속은 메시지를 포스팅 합니다.

2. 이때 어플리케이션은 몇몇 다른 메시지를 처리하고 있습니다.

3. 처리하고 있는동안에 어플리케이션이 ioctlsocket( s, FIONREAD...)를 호출하고, 소켓에 읽을 수 있는 데이터가 있다는 것을 알아냅니다.

4. 어플리케이션은 recv( s, ...)를 호출하여 데이터를 읽습니다.

5. 1.에서 이미 수신된 메시지를 post했었죠? 즉, 메시지 큐에 메시지는 남아있게 되므로 데이터를 읽을 수 있는상태라는 FD_READ 가 발생합니다.

6. 어플리케이션은 recv( s, ... )를 호출하겠죠? 하지만, WSAEWOULDBLOCK 에러가 발생하게 됩니다.

윈도즈 소켓은 특정한 네트웍 이벤트 메시지로 어플리케이션 윈도우로 항상 메시지를 주지 않습니다. 이러한 어플리케이션 윈도우로의 이벤트의 통보는, 어플리케이션이 네트웍 이벤트의 암시적 재활성화(re-enables) 통지를 위한 함수를 호출하기 전까지 (메시지큐에) 붙여지지 않습니다.
영문을 고대루 해석하려 하니까 좀 어색한 것 같죠? 쉽게 예를 들어서 설명하자면, 소켓으로부터 읽혀질 데이터가 있다고 가정 합시다. 어플리케이션이 FD_READ 이벤트의 통보를 활성화 했었다면, 윈도우즈 소켓은 지정된 윈도우로 하나의 FD_READ 이벤트를 전송할 것입니다. 이때 어플리케이션이
recv함수나 recvfrom 함수를 호출해야만 FD_READ 이벤트 생성이 다시 활성화 된다는 것입니다. 동시다발적으로 메시지가 도착하지는 않는다는 말입니다. recv 함수나 recvfrom 함수가 호출된 후에 소켓의 수신큐에 더 많은 데이터가 기다리고 있을 경우 다른 FD_READ 이벤트가 지정된 윈도우로 전송될 것입니다. 이렇게 메시지를 재 활성화 하는 함수를 "re-enabling function" 이라고 합니다. 아래의 표에 이러한 함수들을 나열해 보았습니다.

Event Re-enabling function
FD_READ recv, recvfrom, WSARecv, or WSARecvFrom
FD_WRITE send, sendto, WSASend, or WSASendTo
FD_OOB recv, recvfrom, WSARecv, or WSARecvFrom
FD_ACCEPT accept or WSAAccept ( condition 함수가 CF_DEFER인 WSATRY_AGAIN 일 경우는 제외)
FD_CONNECT 없음
FD_CLOSE 없음
FD_QOS SIO_GET_QOS 컴맨드로 호출된 WSAIoctl
FD_GROUP_QOS SIO_GET_GROUP_QOS 컴맨드로 호출된 WSAIoctl
FD_ROUTING
_INTERFACE_CHANGE
SIO_ROUTING_INTERFACE_CHANGE 컴맨드로 호출된 WSAIoctl
FD_ADDRESS_LIST
_CHANGE
SIO_ADDRESS_LIST_CHANGE 컴맨드로 호출된 WSAIoctl

FD_READ, FD_OOB, 그리고 FD_ACCEPT 이벤트에 대한 메시지 포스팅 방법은 "level-triggered"라고 합니다. 무슨 말이냐구요? 만약 재활성화 루틴이 호출되고, 이와 관련된 상태가 루틴 호출후에도 여전히 남아 있다면, 메시지는 어플리케이션에 다시 포스팅 됩니다. 이러한 포스팅 방법으로 어플리케이션은 메시지 구동 방식이 됩니다. 아직 이해가 잘 않되시죠? 아래의 순서를 한번 생각해 보세요... 지금 제가 한말을 쉽게 이해 할 수 있을 겁니다.

1. 네트웍 전송/수신 스택이 소켓에 100 바이트의 데이터를 수신받고, 윈속이 FD_READ 메시지를 포스팅 했습니다.

2. 어플리케이션이 recv( s, buffer, 50, 0 )을 호출해서 50바이트를 수신했습니다.

3. 읽을 데이터가 여전히 남아있는 동안 FD_READ 메시지가 포스팅 됩니다.

이러한 구조상에서, 어플리케이션은 하나의 FD_READ 메시지에 대해서 모든 가능한 데이터를 읽어낼 필요가 없습니다. 각각의 FD_READ 메시지에 대해서 하나의 recv를 사용하는 것이 적절한 방법입니다. 만약 어플리케이션이 하나의 FD_READ에 대해서 여러개의 recv를 호출할 경우, 여러개의 FD_READ 메시지를 수신할 수도 있습니다. 이러한 어플리케이션에서는 recv함수를 호출하기전에 WSAAsyncSelect 함수를 FD_READ 이벤트를 셋팅하지 않는 방법으로 FD_READ 메시지 수신을 막아 버려야할 필요가 있습니다.

FD_QOS 그리고 FD_GROUP_QOS 이벤트는 "edge triggered"로 간주됩니다. 메시지는 Quality Of Service가 바뀌었을 때 정확히 한번 포스팅 됩니다. 게다가 메시지는 프로바이더가 QOS에서의 다른 변화를 감지하든지, 아니면, 어플리케이션이 소켓에 대한 QOS를 재설정할 때 까지 메시지는 수신되지 않습니다.

FD_ROUTING_INTERFACE_CHANGE 메시지는 SIO_ROUTING_INTERFACE_CHANGE 컴맨드로 WSAIoctl 함수가 호출될 때 포스팅 됩니다.

FD_ADDRESS_LIST_CHANGE 메시지는 SIO_ADDRESS_LIST_CHANGE 컴맨드로 WSAIoctl 함수가 호출될 때 포스팅 됩니다.

만약 어플리케이션이 WSAAsyncSelect함수를 호출하거나 재활성(re-enabling)함수를 호출했을 때 이미 이벤트가 발생되었다면, 이때의 메시지는 적절히 포스팅 됩니다. 이해를 쉽게 하기위해 아래의 일어날 수 순서 상황을 생각해 보세요.

1. 어플리케이션이 생성한 소켓에 대해서 listen 함수를 호출 했습니다.

2. 접속 요구가 들어왔으나 아직 accept 하지 않았습니다.

3. 어플리케이션은 이 소켓에 대해서 FD_ACCEPT로 WSAAsyncSelect 함수를 호출하였습니다. 이때 이벤트의 영속성이 보존되기 때문에 윈속은 FD_ACCEPT 메시지를 바로 포스팅 하게 됩니다.

FD_WRITE 이벤트는 약간 다르게 운용됩니다. 즉, 소켓이 connect/WSAConnect 함수의 호출로 첨 접속되었을 때, 또는 accept/WSAAccept 함수로 접속허용되었을 때, 또는, send 연산이 WSAEWOULDBLOCK 으로 실패(비동기소켓은 항상 WSAEWOULDBLOCK입니다)한 상태에서 전송용 버퍼공간이 사용 가능해졌을 때 FD_WRITE 메시지는 포스팅 됩니다. 따라서 어플리케이션은 FD_WRITE 메시지를 받았을 때 데이터의 전송이 가능하다고 판단 할 수 있습니다.

FD_OOB 이벤트는 소켓이 out-of-band 데이터를 부분적으로 수신하여 나열할 때만 사용됩니다. 만약 소켓이 out-of-band 데이터를 인라인 방식으로 수신하도록 나열 한다면, out-of-band데이터는 일반 데이터와 같이 다루어 지게 됩니다. 이때, 어플리케이션은 interest(?)를 등록해야 합니다. 일반데이터와 같이 다루어 진다는 의미는 뭔지 아시겠죠? FD_OOB 이벤트가 아닌 FD_READ이벤트가 발생했을 때 데이터를 수신한다는 의미입니다. 어플리케이션은 out-of-band 데이터가 SO_OOBINLINE 옵션으로 setsockopt함수나 getsockopt함수를 사용하여 핸들링 하는 방법을 설정할 수 있습니다.

FD_CLOSE 메시지의 에러코드는 소켓이 우아한닫힘(graceful close)인지 그렇지 않은 닫힘인지를 나타냅니다. 만약 에러코드가 0이라면, 소켓은 우아한닫힘 이라는 의미이고, 에러코드가 WSAECONNRESET 이라면, 소켓의 가상 회선망이 리셋되었다는 것을 의미합니다. 이러한 것들은 SOCK_STREAM과 같은 접속 지향형 소켓일 경우에만 사용될 수 있는 것들입니다.

FD_CLOSE 메시지는 소켓과 연관된 가상 회선망이 끊겼다는 것을 수신받았을 때 포스팅 됩니다. TCP 의 경우는 접속이 TIME WAIT 나 CLOSE WAIT 상태로 들어갔을 때 FD_CLOSE 메시지가 포스팅 되게 됩니다. 즉, 원격 종단점에서의 전송영역의 셧다운이나 closesocket 함수의 호출의 결과로 일어날 수 있는 메시지입니다. FD_CLOSE 메시지는 모든 데이터가 소켓으로부터 읽혀지고 난 후에 포스팅 됩니다 그렇긴 해도, 최대한 손실된 데이터들을 피하고자 한다면, FD_CLOSE 메시지를 받은 후에 남아있는 데이터들을 체크하는 것이 좋겠죠?

아래에 지금까지 설명했던 비동기 통지 메시지에 대한 이벤트와 상태들을 간략히 요약해 놓았습니다.

FD_READ:  

    WSAAsyncSelect 함수가 호출 되고나서, 수신할수 있는 데이터가 있을 때

    데이터가 로컬 호스트로 도착하고, FD_READ 가 아직 포스팅되지 않았을 때

    recv 함수나 recvfrom 함수가 호출된 후에, 수신가능한 데이터가 여전히 남아 있을 때

    SO_OOBINLINE 옵션으로 setsockopt 함수를 호출하여 out-of-band 데이터가 일반데이터 처럼 취급되었을 때 수신할 out-of-band 데이터가 있을 때

FD_WRITE:

    WSAAsyncSelect 함수가 호출 되고, send sendto 함수가 사용가능 할 때

    connectaccept함수가 호출되고 나서, 접속이 완료 되었을 때

    sendsendto 함수가 WSAEWOULDBLOCK으로 실패한후, 전송용 버퍼가 사용 가능 할 때

    비접속 지향 소켓의 바인드 후에, FD_WRITE가 현재 발생되었거나 그렇지 않았을 때. (이러한 비접속 지향형 소켓은 바인드 후에 바로 데이터를 전송할 수 있는 상태의 소켓입니다.)

FD_OOB: setsockopt 함수를 이용해서 SO_OOBINLINE 옵션을 무시한 경우에만. (기본 설정값 이죠)

    WSAAsyncSelect 함수가 호출 되고나서, OOB 데이터를 MSG_OOB 플래그로 수신할수 있을 때.

    OOB데이터가 로컬 호스트로 도착하고, FD_OOB 가 아직 포스팅 되지 않았을 때.

    recv 또는 recvfrom 함수가 호출되고나서, 수신가능한 OOB 데이터가 남아 있을때.

FD_ACCEPT:

    WSAAsyncSelect 함수가 호출되고 나서, 허용가능한 접속 요청이 있을 때.

    접속 요청이 로컬호스트로 도착하고, FD_ACCEPT 가 아직 포스팅 되지 않았을 때.

    accept 함수의 호출 후에, 허용가능한 다른 접속 요청이 있을때.

FD_CONNECT:

    WSAAsyncSelect 함수가 호출되고 나서, 접속요청 작업의 완료가 있었던 경우.

    connect 함수가 호출되고 난 후에 접속 작업이 완료되었을 때.

    WSAJoinLeaf 함수의 호출 후에 join 연산이 완료 되었을 때.

    connect, WSAConnect 또는 WSAJoinLeaf 함수가 접속지향형 비동기 모드에서 호출된 후에, 연산이 시작되고 나면, WSAEWOULDBLOCK 이라는 에러코드가 발생될 것입니다. 왜냐구? 비동기기 때문이쥐... 암튼 이러한 비동기 함수의 호출후에 접속이 성공했든 실패했든간에 FD_CONNECT 메시지가 발생합니다. 클라이언트는 FD_CONNECT 메시지가 발생되었을 때 정말로 접속이 성공적으로 일어났는지 아닌지를 판단하기 위해서 에러코드를 체크 해 보아야 합니다.

FD_CLOSE: SOCK_STREAM과 같은 접속 지향형 소켓에서만 발생합니다.

    WSAAsyncSelect 함수가 호출되고, 접속이 종료 되었을때.

    원격지 소켓시스템이 우아한 종료(graceful close)를 한후에, 수신큐에 아무런 데이터가 없는 경우.

    로컬 시스템이 shutdown함수로 우아한 종료(graceful close)를 하고, 원격지 시스템이 이에 End of Data 로 응답하고(TCP 프로토콜의 FIN 이 1로셋팅된 경우), 수신가능한 데이터가 남아있지 않은 경우 발생.

    원격지 시스템이 접속을 리셋 시켰을 때(TCP 프로토콜의 RST가 1로 셋팅된 경우) 발생되는데, 이때 lParam은 WSAECONNRESET 에러 코드를 가지고 있게 됩니다.

    Note : closesocket 함수를 호출하고 난 후에 FD_CLOSE 메시지는 포스팅 되지 않습니다.

FD_QOS:

    WSAAsyncSelect 함수가 호출되고 나서, 소켓과 연관된 Quality Of Service가 변경된 경우

    SIO_GET_QOS 컴맨드로 WSAIoctl 함수가 호출된후, QOS가 변경된 경우

FD_GROUP_QOS (소켓 그룹으로 미래에 사용하기 위해 예약 되었다고 하네요?):

    WSAAsyncSelect 함수가 호출되고 나서, 소켓과 연관된 Group Quality Of Service가 변경된 경우

    SIO_GET_GROUP_QOS 컴맨드로 WSAIoctl 함수가 호출된후, GROUP QOS가 변경된 경우

FD_ROUTING_INTERFACE_CHANGE:

    SIO_ROUTING_INTERFACE_CHANGE 컴맨드로 WSAIoctl 함수가 호출되고 나서 로컬 인터페이스가 변경되었을 때

FD_ADDRESS_LIST_CHANGE

    SIO_ADDRESS_LIST_CHANGE 컴맨드로 WSAIoctl 함수가 호출되고 나서 로컬어드레스의 리스트가 변경되었을 때.

     

Return Values

에러가 없을 경우 WSAAsyncSelect 함수는 0을 반환 합니다. 에러가 있을 경우 SOCKET_ERROR를 반환 하며, WSAGetLastError 함수를 호출하여 지정된 에러코드를 검색할 수 있습니다.

 

Error Codes

WSANOTINITIALISED

이 함수를 사용하기 이전에 WSAStartup 함수를 성공적으로 호출해야 합니다.

WSAENETDOWN

네트웍 서브 시스템에서 에러가 났습니다.

WSAEINVAL 함수의 매개변수가 잘못 사용되었습니다.
WSAEINPROGRESS

블럭킹 윈속 v1.1이 진행상태에 있거나, 서비스 프로바이더가 아직 콜백함수를 진행하고 있습니다.

WSAENOTSOCK 지정된 소켓기술자가 소켓이 아닙니다.

추가적인 에러코드는 어플리케이션 윈도우가 메시지를 수신할 때 얻어낼 수 있습니다. 지금부터 나열하게될 에러코드는 lParam 매개변수를 WSAGETSELECTERROR 매크로를 이용하여 뽑아낸 에러코드 값입니다.

Event: FD_CONNECT

Error Code Meaning
WSAEAFNOSUPPORT 지정된 주소 패밀리가 본 소켓에서 사용될 수 없는 형태 입니다.
WSAECONNREFUSED 접속시도가 강제로 종료되었습니다.
WSAENETUNREACH 네트웍이 현재 지정된 호스트로 연결될 수 없습니다.
WSAEFAULT name 또는 namelen 매개변수가 올바른 형태가 아닙니다.
WSAEINVAL 소켓이 이미 특정한 어드레스와 바이드 되어 있습니다.
WSAEISCONN 소켓이 이미 접속상태에 있습니다.
WSAEMFILE 더 이상 소켓 기술자를 할당 할 수 없습니다.
WSAENOBUFS 사용할 수 있는 버퍼 공간이 없어서 접속할 수 없습니다.
WSAENOTCONN 소켓이 접속되어지지 못했습니다.
WSAETIMEDOUT 접속을 완료하지 못하고 타임아웃 되었습니다.

Event: FD_CLOSE

Error Code Meaning
WSAENETDOWN

네트웍 서브 시스템에서 에러가 났습니다.

WSAECONNRESET 접속이 원격지 로부터 리셋 되었습니다.
WSAECONNABORTED 접속이 타임아웃이나 다른 에러로 인하여 터미네이트 되었습니다.

Event: FD_READ
Event: FD_WRITE
Event: FD_OOB
Event: FD_ACCEPT
Event: FD_QOS
Event: FD_GROUP_QOS
Event: FD_ADDRESS_LIST_CHANGE

Error Code Meaning
WSAENETDOWN 네트웍 서브시스템에서 에러가 났습니다.

Event: FD_ROUTING_INTERFACE_CHANGE

Error Code Meaning
WSAENETUNREACH 지정한 목적지에 더 이상 도달 할 수 없습니다.
WSAENETDOWN 네트웍 서브시스템에서 에러가 났습니다.
 

QuickInfo

Windows NT : 사용가능
Windows : 사용가능
Windows CE : 지원되지 않음
Header :
          Win16/32 : winsock.h
          Win32-II : winsock2.h
Import Library :
          Win16 : winsock.lib
          Win32 : wsock32.lib
          Win32-II : ws2_32.lib

See Also