WSAEnumNetworkEvents 함수(winsock2.h)
WSAEnumNetworkEvents 함수는 표시된 소켓에 대한 네트워크 이벤트 발생, 내부 네트워크 이벤트 레코드 지우기 및 이벤트 개체 재설정(선택 사항)을 검색합니다.
구문
int WSAAPI WSAEnumNetworkEvents(
[in] SOCKET s,
[in] WSAEVENT hEventObject,
[out] LPWSANETWORKEVENTS lpNetworkEvents
);
매개 변수
[in] s
소켓을 식별하는 설명자입니다.
[in] hEventObject
재설정할 연결된 이벤트 개체를 식별하는 선택적 핸들입니다.
[out] lpNetworkEvents
발생한 네트워크 이벤트 레코드 및 연결된 오류 코드로 채워진 WSANETWORKEVENTS 구조체에 대한 포인터입니다.
반환 값
작업이 성공한 경우 반환 값은 0입니다. 그렇지 않으면 SOCKET_ERROR 값이 반환되고 WSAGetLastError를 호출하여 특정 오류 번호를 검색할 수 있습니다.
오류 코드 | 의미 |
---|---|
이 함수를 사용하기 전에 성공적인 WSAStartup 호출이 발생해야 합니다. | |
네트워크 하위 시스템이 실패했습니다. | |
지정된 매개 변수 중 하나가 잘못되었습니다. | |
차단 Windows 소켓 1.1 호출이 진행 중이거나 서비스 공급자가 여전히 콜백 함수를 처리하고 있습니다. | |
설명자가 소켓이 아닙니다. | |
lpNetworkEvents 매개 변수는 사용자 주소 공간의 유효한 부분이 아닙니다. |
설명
WSAEnumNetworkEvents 함수는 이 함수의 마지막 호출 이후 표시된 소켓에 대해 발생한 네트워크 이벤트를 검색하는 데 사용됩니다. 이벤트 개체를 하나 이상의 네트워크 이벤트와 연결하는 WSAEventSelect와 함께 사용하기 위한 것입니다. 네트워크 이벤트 기록은 WSAEventSelect가 0이 아닌 lNetworkEvents 매개 변수를 사용하여 호출되고 lNetworkEvents 매개 변수가 0으로 설정된 WSAEventSelect에 대한 다른 호출이 수행될 때까지 또는 WSAAsyncSelect를 호출할 때까지 계속 적용됩니다.
WSAEnumNetworkEvents는WSAEventSelect를 통해 지명된 네트워크 활동 및 오류만 보고합니다. select 및 WSAAsyncSelect에 대한 설명을 참조하여 해당 함수가 네트워크 활동 및 오류를 보고하는 방법을 알아봅니다.
네트워크 이벤트에 대한 소켓의 내부 레코드는 lpNetworkEvents에서 참조하는 구조로 복사되며, 그 후에는 내부 네트워크 이벤트 레코드가 지워집니다. hEventObject 매개 변수가 NULL이 아니면 표시된 이벤트 개체도 다시 설정됩니다. Windows Sockets 공급자는 네트워크 이벤트 레코드를 복사하고, 지우고, 연결된 이벤트 개체를 다시 설정하는 작업이 원자성임을 보장하므로, 다음에 추천된 네트워크 이벤트가 발생하면 이벤트 개체가 설정됩니다. SOCKET_ERROR 반환하는 이 함수의 경우 연결된 이벤트 개체가 다시 설정되지 않고 네트워크 이벤트 레코드가 지워지지 않습니다.
WSANETWORKEVENTS 구조체의 lNetworkEvents 멤버는 발생한 FD_XXX 네트워크 이벤트를 나타냅니다. iErrorCode 배열은 lNetworkEvents의 이벤트 비트 위치에 해당하는 배열 인덱스와 관련된 오류 코드를 포함하는 데 사용됩니다. FD_READ_BIT 및 FD_WRITE_BIT 같은 식별자를 사용하여 iErrorCode 배열을 인덱싱할 수 있습니다. iErrorCode 배열의 해당 요소만 lNetworkEvents 매개 변수에 설정된 비트에 해당하는 것으로 설정됩니다. 다른 매개 변수는 수정되지 않습니다(새 FD_ROUTING_INTERFACE_CHANGE 및 FD_ADDRESS_LIST_CHANGE 이벤트를 인식하지 못하는 애플리케이션과의 이전 버전과의 호환성을 위해 중요합니다).
다음 오류 코드는 해당 네트워크 이벤트와 함께 반환될 수 있습니다.
이벤트: FD_CONNECT
오류 코드 | 의미 |
---|---|
WSAEAFNOSUPPORT | 지정된 패밀리의 주소는 이 소켓에서 사용할 수 없습니다. |
WSAECONNREFUSED | 연결 시도가 강제로 거부되었습니다. |
WSAENETUNREACH | 현재 이 호스트에서 네트워크에 연결할 수 없습니다. |
WSAENOBUFS | 사용할 수 있는 버퍼 공간이 없습니다. 소켓을 연결할 수 없습니다. |
WSAETIMEDOUT | 연결을 설정하지 않고 연결 시도가 시간 초과됨 |
이벤트: FD_CLOSE
오류 코드 | 의미 |
---|---|
WSAENETDOWN | 네트워크 하위 시스템이 실패했습니다. |
WSAECONNRESET | 원격 쪽에서 연결을 다시 설정했습니다. |
WSAECONNABORTED | 제한 시간 또는 기타 오류로 인해 연결이 종료되었습니다. |
이벤트: FD_ACCEPT
이벤트: FD_ADDRESS_LIST_CHANGE
이벤트: FD_GROUP_QOS
이벤트: FD_QOS
이벤트: FD_OOB
이벤트: FD_READ
이벤트: FD_WRITE
오류 코드 | 의미 |
---|---|
WSAENETDOWN | 네트워크 하위 시스템이 실패했습니다. |
이벤트: FD_ROUTING_INTERFACE_CHANGE
오류 코드 | 의미 |
---|---|
WSAENETUNREACH | 지정된 대상에 더 이상 연결할 수 없습니다. |
WSAENETDOWN | 네트워크 하위 시스템이 실패했습니다. |
예제 코드
다음 예제에서는 WSAEnumNetworkEvents 함수를 사용하는 방법을 보여 줍니다.#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
int main()
{
//-------------------------
// Declare and initialize variables
WSADATA wsaData;
int iResult;
SOCKET SocketArray[WSA_MAXIMUM_WAIT_EVENTS], ListenSocket;
WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];
WSANETWORKEVENTS NetworkEvents;
sockaddr_in InetAddr;
DWORD EventTotal = 0;
DWORD Index;
DWORD i;
HANDLE NewEvent = NULL;
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0) {
wprintf(L"WSAStartup failed with error: %d\n", iResult);
return 1;
}
//-------------------------
// Create a listening socket
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
wprintf(L"socket function failed with error: %d\n", WSAGetLastError() );
return 1;
}
InetAddr.sin_family = AF_INET;
InetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InetAddr.sin_port = htons(27015);
//-------------------------
// Bind the listening socket
iResult = bind(ListenSocket, (SOCKADDR *) & InetAddr, sizeof (InetAddr));
if (iResult != 0) {
wprintf(L"bind failed with error: %d\n", WSAGetLastError() );
return 1;
}
//-------------------------
// Create a new event
NewEvent = WSACreateEvent();
if (NewEvent == NULL) {
wprintf(L"WSACreateEvent failed with error: %d\n", GetLastError() );
return 1;
}
//-------------------------
// Associate event types FD_ACCEPT and FD_CLOSE
// with the listening socket and NewEvent
iResult = WSAEventSelect(ListenSocket, NewEvent, FD_ACCEPT | FD_CLOSE);
if (iResult != 0) {
wprintf(L"WSAEventSelect failed with error: %d\n", WSAGetLastError() );
return 1;
}
//-------------------------
// Start listening on the socket
iResult = listen(ListenSocket, 10);
if (iResult != 0) {
wprintf(L"listen failed with error: %d\n", WSAGetLastError() );
return 1;
}
//-------------------------
// Add the socket and event to the arrays, increment number of events
SocketArray[EventTotal] = ListenSocket;
EventArray[EventTotal] = NewEvent;
EventTotal++;
//-------------------------
// Wait for network events on all sockets
Index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);
Index = Index - WSA_WAIT_EVENT_0;
//-------------------------
// Iterate through all events and enumerate
// if the wait does not fail.
for (i = Index; i < EventTotal; i++) {
Index = WSAWaitForMultipleEvents(1, &EventArray[i], TRUE, 1000, FALSE);
if ((Index != WSA_WAIT_FAILED) && (Index != WSA_WAIT_TIMEOUT)) {
WSAEnumNetworkEvents(SocketArray[i], EventArray[i], &NetworkEvents);
}
}
//...
return 0;
Windows Phone 8: 이 함수는 Windows Phone 8 이상에서 Windows Phone 스토어 앱에서 지원됩니다.
Windows 8.1 및 Windows 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 |