WSAEventSelect 함수(winsock2.h)

WSAEventSelect 함수는 지정된 FD_XXX 네트워크 이벤트 집합과 연결할 이벤트 개체를 지정합니다.

구문

int WSAAPI WSAEventSelect(
  [in] SOCKET   s,
  [in] WSAEVENT hEventObject,
  [in] long     lNetworkEvents
);

매개 변수

[in] s

소켓을 식별하는 설명자입니다.

[in] hEventObject

지정된 FD_XXX 네트워크 이벤트 집합과 연결할 이벤트 개체를 식별하는 핸들입니다.

[in] lNetworkEvents

애플리케이션에 관심이 있는 FD_XXX 네트워크 이벤트의 조합을 지정하는 비트 마스크입니다.

반환 값

애플리케이션의 네트워크 이벤트 및 연결된 이벤트 개체 사양이 성공한 경우 반환 값은 0입니다. 그렇지 않으면 SOCKET_ERROR 값이 반환되고 WSAGetLastError를 호출하여 특정 오류 번호를 검색할 수 있습니다.

selectWSAAsyncSelect 함수의 경우와 마찬가지로 WSAEventSelect는 데이터 전송 작업(송신 또는 사각형)이 즉시 성공할 것으로 예상하는 시기를 결정하는 데 자주 사용됩니다. 그럼에도 불구하고 이벤트 개체가 설정되고 WSAEWOULDBLOCK 을 즉시 반환하는 Windows 소켓 호출을 실행할 수 있도록 강력한 애플리케이션을 준비해야 합니다. 예를 들어 다음과 같은 작업 시퀀스가 가능합니다.

  • 데이터는 소켓 s에 도착합니다. Windows 소켓은 WSAEventSelect 이벤트 개체를 설정합니다.
  • 애플리케이션은 몇 가지 다른 처리를 수행합니다.
  • 처리하는 동안 애플리케이션은 ioctlsocket(, FIONREAD...)을 발급하고 읽을 준비가 된 데이터가 있음을 알 수 있습니다.
  • 애플리케이션은 데이터를 읽기 위해 recv(s,...)를 발급합니다.
  • 결국 애플리케이션은 WSAEventSelect에 지정된 이벤트 개체를 기다립니다. 이 개체는 데이터를 읽을 준비가 되었음을 나타내는 즉시 를 반환합니다.
  • 애플리케이션은 오류 WSAEWOULDBLOCK으로 실패하는 recv(s,...)를 발급합니다.
내부 네트워크 이벤트 레코드에서 해당 비트를 설정하여 네트워크 이벤트의 발생을 성공적으로 기록하고 연결된 이벤트 개체에 신호를 전송한 후에는 애플리케이션이 해당 네트워크 이벤트의 설정 및 관련 이벤트 개체의 신호를 암시적으로 다시 활성화하는 함수 호출을 수행할 때까지 해당 네트워크 이벤트에 대한 추가 작업이 수행되지 않습니다.
네트워크 이벤트 함수 다시 사용
FD_READ
recv, recvfrom, WSARecv, WSARecvEx 또는 WSARecvFrom 함수입니다.
FD_WRITE
send, sendto, WSASend 또는 WSASendTo 함수입니다.
FD_OOB
recv, recvfrom, WSARecv, WSARecvEx 또는 WSARecvFrom 함수입니다.
FD_ACCEPT
반환된 오류 코드가 WSATRY_AGAIN 조건 함수가 CF_DEFER 반환되었음을 나타내는 경우가 아니면 accept, AcceptEx 또는 WSAAccept 함수입니다.
FD_CONNECT
없음
FD_CLOSE
없음
FD_QOS
명령 SIO_GET_QOSWSAIoctl 함수입니다.
FD_GROUP_QOS
예약되어 있습니다.
FD_ROUTING_ INTERFACE_CHANGE
명령 SIO_ROUTING_INTERFACE_CHANGEWSAIoctl 함수입니다.
FD_ADDRESS_ LIST_CHANGE
명령 SIO_ADDRESS_LIST_CHANGEWSAIoctl 함수입니다.
 

다시 시작 루틴에 대한 호출은 실패하더라도 관련 네트워크 이벤트 및 이벤트 개체에 대한 기록 및 신호가 다시 설정됩니다.

FD_READ, FD_OOB 및 FD_ACCEPT 네트워크 이벤트의 경우 네트워크 이벤트 기록 및 이벤트 개체 신호가 수준 트리거됩니다. 즉, 다시 시작 루틴이 호출되고 호출 후에도 관련 네트워크 조건이 여전히 유효한 경우 네트워크 이벤트가 기록되고 연결된 이벤트 개체가 설정됩니다. 이렇게 하면 애플리케이션이 이벤트 기반이 되며 한 번에 도착하는 데이터의 양과 관련이 없습니다. 다음과 같은 시퀀스를 고려해 보세요.

  1. 전송 공급자는 소켓 에서 100바이트의 데이터를 수신하고 WS2_32.DLL FD_READ 네트워크 이벤트를 기록하고 연결된 이벤트 개체를 설정합니다.
  2. 애플리케이션은 recv(s, buffptr, 50, 0)를 발행하여 50바이트를 읽습니다.
  3. 전송 공급자는 WS2_32.DLL FD_READ 네트워크 이벤트를 기록하도록 하고, 읽을 데이터가 아직 없으므로 연결된 이벤트 개체를 다시 설정합니다.
이러한 의미 체계를 사용하면 애플리케이션이 FD_READ 네트워크 이벤트에 대한 응답으로 사용 가능한 모든 데이터를 읽을 필요가 없습니다. 각 FD_READ 네트워크 이벤트에 대한 응답으로 단일 사각형 이 적절합니다.

FD_QOS 이벤트는 에지 트리거로 간주됩니다. 서비스 품질 변경이 발생할 때 메시지가 정확히 한 번 게시됩니다. 공급자가 서비스 품질의 추가 변화를 감지하거나 애플리케이션이 소켓에 대한 서비스 품질을 재협상할 때까지 추가 메시지가 나오지 않습니다.

FD_ROUTING_INTERFACE_CHANGE 및 FD_ADDRESS_LIST_CHANGE 이벤트도 에지 트리거로 간주됩니다. 애플리케이션이 SIO_ROUTING_INTERFACE_CHANGE 사용하여 WSAIoctl을 실행하여 알림을 요청한 후 변경이 발생하면 메시지가 정확히 한 번 게시되거나 그에 해당하는 SIO_ADDRESS_LIST_CHANGE. 애플리케이션이 IOCTL을 재발행하고 IOCTL이 발급된 이후 다른 변경 내용이 검색될 때까지 다른 메시지는 나오지 않습니다.

애플리케이션이 WSAEventSelect 를 호출하거나 다시 설정 함수가 호출될 때 네트워크 이벤트가 이미 발생한 경우 네트워크 이벤트가 기록되고 연결된 이벤트 개체가 적절하게 설정됩니다. 예를 들어 다음 시퀀스를 살펴봅니다.

  1. 애플리케이션이 수신 대기를 호출합니다.
  2. 연결 요청이 수신되었지만 아직 수락되지 않았습니다.
  3. 애플리케이션은 소켓에 대한 FD_ACCEPT 네트워크 이벤트에 관심이 있음을 지정하는 WSAEventSelect 를 호출합니다. 네트워크 이벤트의 지속성으로 인해 Windows Sockets는 FD_ACCEPT 네트워크 이벤트를 기록하고 연결된 이벤트 개체를 즉시 설정합니다.
FD_WRITE 네트워크 이벤트는 약간 다르게 처리됩니다. FD_WRITE 네트워크 이벤트는 connect,ConnectEx, WSAConnect, WSAConnectByList 또는 WSAConnectByName 함수에 대한 호출로 소켓이 처음 연결되거나 소켓이 accept, AcceptEx 또는 WSAAccept 함수로 수락된 후 WSAEWOULDBLOCK 및 버퍼 공간으로 전송이 실패하면 기록됩니다. 따라서 애플리케이션은 첫 번째 FD_WRITE 네트워크 이벤트 설정부터 송신이 WSAEWOULDBLOCK을 반환할 때까지 전송이 지속될 수 있다고 가정할 수 있습니다. 이러한 오류가 발생하면 애플리케이션은 FD_WRITE 네트워크 이벤트가 기록되고 연결된 이벤트 개체가 설정될 때 전송이 다시 가능하다는 것을 알게 됩니다.

FD_OOB 네트워크 이벤트는 소켓이 OOB 데이터를 별도로 수신하도록 구성된 경우에만 사용됩니다. 소켓이 OOB 데이터를 인라인으로 수신하도록 구성된 경우 OOB(긴급) 데이터는 일반 데이터로 처리되고 애플리케이션은 관심을 등록해야 하며 네트워크 이벤트가 아닌 FD_READ 네트워크 이벤트를 FD_OOB. 애플리케이션은 SO_OOBINLINE 옵션에 대해 setsockopt 또는 getsockopt 를 사용하여 OOB 데이터를 처리하는 방법을 설정하거나 검사할 수 있습니다.

FD_CLOSE 네트워크 이벤트의 오류 코드는 소켓 닫기가 정상인지 아니면 중단되었는지를 나타냅니다. 오류 코드가 0이면 닫기는 정상입니다. 오류 코드가 WSAECONNRESET이면 소켓의 가상 회로가 다시 설정되었습니다. 이는 SOCK_STREAM 같은 연결 지향 소켓에만 적용됩니다.

FD_CLOSE 네트워크 이벤트는 소켓에 해당하는 가상 회로에 대한 닫기 표시가 수신될 때 기록됩니다. TCP 용어에서 이는 연결이 TIME WAIT 또는 CLOSE WAIT 상태로 전환될 때 FD_CLOSE 기록됨을 의미합니다. 이로 인해 원격 엔드가 송신 쪽 또는 closesocket에서 종료를 수행합니다. FD_CLOSE 소켓에서 모든 데이터를 읽은 후에 게시됩니다. 애플리케이션은 데이터 손실 가능성을 방지하기 위해 FD_CLOSE 수신 시 남은 데이터를 검사 합니다. 자세한 내용은 정상 종료, 느린 옵션 및 소켓 닫기 및종료 함수에 대한 섹션을 참조하세요.

Windows 소켓은 가상 회로의 폐쇄를 나타내는 FD_CLOSE 네트워크 이벤트만 기록합니다. 이 조건을 나타내기 위해 FD_READ 네트워크 이벤트를 기록하지 않습니다.

FD_QOS 또는 FD_GROUP_QOS 네트워크 이벤트는 소켓 s와 연결된 흐름 사양의 매개 변수가 있을 때 기록됩니다. 애플리케이션은 명령 SIO_GET_QOSWSAIoctl을 사용하여 소켓 s에 대한 현재 서비스 품질을 가져와야 합니다.

FD_ROUTING_INTERFACE_CHANGE 네트워크 이벤트는 WSAIoctl 에 지정된 대상에 도달하는 데 사용해야 하는 로컬 인터페이스가 이러한 IOCTL을 실행한 후 SIO_ROUTING_INTERFACE_CHANGE 변경된 경우에 기록됩니다.

FD_ADDRESS_LIST_CHANGE 네트워크 이벤트는 WSAIoctl 에서 SIO_ADDRESS_LIST_CHANGE 적용한 후 애플리케이션이 변경 내용을 바인딩할 수 있는 소켓에 대한 프로토콜 패밀리의 주소 목록이 기록될 때 기록됩니다.

오류 코드 의미
WSANOTINITIALISED 이 함수를 사용하기 전에 성공적인 WSAStartup 호출이 발생해야 합니다.
WSAENETDOWN 네트워크 하위 시스템이 실패했습니다.
WSAEINVAL 지정된 매개 변수 중 하나가 잘못되었거나 지정된 소켓이 잘못된 상태입니다.
WSAEINPROGRESS 차단 Windows Sockets 1.1 호출이 진행 중이거나 서비스 공급자가 여전히 콜백 함수를 처리하고 있습니다.
WSAENOTSOCK 설명자가 소켓이 아닙니다.

설명

WSAEventSelect 함수는 선택한 FD_XXX 네트워크 이벤트인 lNetworkEvents와 연결할 이벤트 개체 hEventObject를 지정하는 데 사용됩니다. 이벤트 개체가 지정된 소켓은 s 매개 변수로 식별됩니다. 이벤트 개체는 지정된 네트워크 이벤트가 발생할 때 설정됩니다.

WSAEventSelect 함수는 WSAAsyncSelect와 매우 유사하게 작동하며, 이 차이는 지명된 네트워크 이벤트가 발생할 때 수행되는 작업입니다. WSAAsyncSelect 함수를 사용하면 애플리케이션에서 지정한 Windows 메시지가 게시됩니다. WSAEventSelect는 연결된 이벤트 개체를 설정하고 이 이벤트의 발생을 내부 네트워크 이벤트 레코드에 기록합니다. 애플리케이션은 WSAWaitForMultipleEvents 를 사용하여 이벤트 개체를 기다리거나 폴링하고 WSAEnumNetworkEvents 를 사용하여 내부 네트워크 이벤트 레코드의 콘텐츠를 검색하여 지정된 네트워크 이벤트 중 어떤 이벤트가 발생했는지 확인할 수 있습니다.

WSAEventSelect 함수와 함께 사용되는 이벤트 개체의 상태를 다시 설정하는 적절한 방법은 이벤트 개체의 핸들을 hEventObject 매개 변수의 WSAEnumNetworkEvents 함수에 전달하는 것입니다. 이렇게 하면 이벤트 개체가 다시 설정되고 소켓에서 활성 FD 이벤트의 상태 원자성 방식으로 조정됩니다.

WSAEventSelectWSAEnumNetworkEvents를 통해 네트워크 활동 및 오류를 기록하고 검색할 수 있게 하는 유일한 함수입니다. selectWSAAsyncSelect에 대한 설명을 참조하여 해당 함수가 네트워크 활동 및 오류를 보고하는 방법을 알아봅니다.

WSAEventSelect 함수는 lNetworkEvents 값에 관계없이 소켓 차단 해제 모드로 자동으로 설정합니다. 소켓 다시 차단 모드로 설정하려면 먼저 lNetworkEvents가 0으로 설정되고 hEventObject 매개 변수가 NULL로 설정된 WSAEventSelect 호출을 통해 소켓 s와 연결된 이벤트 레코드를 지워야 합니다. 그런 다음 ioctlsocket 또는 WSAIoctl 을 호출하여 소켓을 다시 차단 모드로 설정할 수 있습니다.

lNetworkEvents 매개 변수는 다음 목록에 지정된 값과 함께 비트 OR 연산자를 사용하여 생성됩니다.

의미
FD_READ 읽기 준비 상태 알림을 받으려고 합니다.
FD_WRITE 쓰기 준비 상태 알림을 받으려고 합니다.
FD_OOB OOB 데이터 도착 알림을 받으려고 합니다.
FD_ACCEPT 들어오는 연결에 대한 알림을 받으려고 합니다.
FD_CONNECT 완료된 연결 또는 멀티포인트 조인 작업에 대한 알림을 받으려고 합니다.
FD_CLOSE 소켓 폐쇄 알림을 받으려고 합니다.
FD_QOS 소켓(QoS 변경 내용)에 대한 알림을 받으려고 합니다.
FD_GROUP_QOS 나중에 소켓 그룹에 사용할 수 있습니다. 소켓 그룹 QoS 변경에 대한 알림을 받으려고 합니다.
FD_ROUTING_ INTERFACE_CHANGE 지정된 대상에 대한 라우팅 인터페이스 변경에 대한 알림을 받으려고 합니다.
FD_ADDRESS_ LIST_CHANGE 소켓의 주소 패밀리에 대한 로컬 주소 목록 변경 알림을 받으려고 합니다.
 

소켓에 대해 WSAEventSelect 를 실행하면 동일한 소켓에 대해 이전 WSAAsyncSelect 또는 WSAEventSelect 가 취소되고 내부 네트워크 이벤트 레코드가 지워지게 됩니다. 예를 들어 이벤트 개체를 읽기 및 쓰기 네트워크 이벤트와 연결하려면 애플리케이션은 다음과 같이 FD_READ 및 FD_WRITE 함께 WSAEventSelect 를 호출해야 합니다.

rc = WSAEventSelect(s, hEventObject, FD_READ|FD_WRITE);

다른 네트워크 이벤트에 대해 다른 이벤트 개체를 지정할 수 없습니다. 다음 코드는 작동하지 않습니다. 두 번째 호출은 첫 번째의 효과를 취소하고 FD_WRITE 네트워크 이벤트만 hEventObject2와 연결됩니다.

rc = WSAEventSelect(s, hEventObject1, FD_READ);
rc = WSAEventSelect(s, hEventObject2, FD_WRITE); //bad

소켓에서 네트워크 이벤트 연결 및 선택을 취소하려면 lNetworkEvents 를 0으로 설정해야 합니다. 이 경우 hEventObject 매개 변수는 무시됩니다.

rc = WSAEventSelect(s, hEventObject, 0);

closesocket을 사용하여 소켓을 닫으면 소켓에 대한 WSAEventSelect에 지정된 네트워크 이벤트의 연결 및 선택도 취소됩니다. 그러나 애플리케이션은 여전히 WSACloseEvent 를 호출하여 이벤트 개체를 명시적으로 닫고 리소스를 해제해야 합니다.

accept 함수를 호출할 때 생성된 소켓은 수락 하는 데 사용되는 수신 대기 소켓과 동일한 속성을 가집니다. 수신 대기 소켓에 대해 설정된 모든 WSAEventSelect 연결 및 네트워크 이벤트 선택 항목이 허용된 소켓에 적용됩니다. 예를 들어 수신 대기 소켓에 hEventObject와 FD_ACCEPT, FD_READ 및 FD_WRITE WSAEventSelect 연결이 있는 경우 해당 수신 대기 소켓에서 허용되는 모든 소켓에는 동일한 hEventObject와 연결된 FD_ACCEPT, FD_READ 및 FD_WRITE 네트워크 이벤트도 있습니다. 다른 hEventObject 또는 네트워크 이벤트가 필요한 경우 애플리케이션은 WSAEventSelect를 호출하여 수락된 소켓 및 원하는 새 정보를 전달해야 합니다.

예제 코드

다음 예제에서는 WSAEventSelect 함수를 사용하는 방법을 보여 줍니다.
//-------------------------
// Declare and initialize variables
SOCKET ListenSocket;
WSAEVENT NewEvent;
sockaddr_in InetAddr;

//-------------------------
// Initialize listening socket
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

//-------------------------
// Bind listening socket
InetAddr.sin_family = AF_INET;
InetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InetAddr.sin_port = htons(27015);

bind (ListenSocket, (SOCKADDR *) &InetAddr, sizeof(InetAddr));

//-------------------------
// Create new event
NewEvent = WSACreateEvent();

//-------------------------
// Associate event types FD_ACCEPT and FD_CLOSE
// with the listening socket and NewEvent
WSAEventSelect( ListenSocket, NewEvent, FD_ACCEPT | FD_CLOSE);

//----------------------
// Listen for incoming connection requests 
// on the created socket
if (listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR)
    printf("Error listening on socket.\n");

printf("Listening on socket...\n");

// Need an event handler added to handle connection requests



Windows Phone 8: 이 함수는 Windows Phone 8 이상에서 Windows Phone 스토어 앱에서 지원됩니다.

Windows 8.1Windows Server 2012 R2: 이 함수는 Windows 8.1, Windows Server 2012 R2 이상에서 Windows 스토어 앱에서 지원됩니다.

요구 사항

요구 사항
지원되는 최소 클라이언트 Windows 8.1, Windows Vista [데스크톱 앱 | UWP 앱]
지원되는 최소 서버 Windows Server 2003 [데스크톱 앱 | UWP 앱]
대상 플랫폼 Windows
헤더 winsock2.h
라이브러리 Ws2_32.lib
DLL Ws2_32.dll

추가 정보

WSAAsyncSelect

WSACloseEvent

WSACreateEvent

WSAEnumNetworkEvents

WSAWaitForMultipleEvents

Winsock 함수

Winsock 참조

shutdown