WSAEnumNetworkEvents 函数 (winsock2.h)
WSAEnumNetworkEvents 函数可发现所指示套接字的网络事件、清除内部网络事件记录以及重置事件对象 (可选) 。
语法
int WSAAPI WSAEnumNetworkEvents(
[in] SOCKET s,
[in] WSAEVENT hEventObject,
[out] LPWSANETWORKEVENTS lpNetworkEvents
);
参数
[in] s
标识套接字的描述符。
[in] hEventObject
标识要重置的关联事件对象的可选句柄。
[out] lpNetworkEvents
指向 WSANETWORKEVENTS 结构的指针,该结构填充了发生的网络事件记录和任何关联的错误代码。
返回值
如果操作成功,则返回值为零。 否则,将返回值SOCKET_ERROR,并且可以通过调用 WSAGetLastError 检索特定的错误号。
错误代码 | 含义 |
---|---|
在使用此函数之前,必须成功调用 WSAStartup 。 | |
网络子系统发生故障。 | |
指定的参数之一无效。 | |
阻止 Windows 套接字 1.1 调用正在进行,或者服务提供商仍在处理回调函数。 | |
:描述符不是套接字。 | |
lpNetworkEvents 参数不是用户地址空间的有效部分。 |
注解
WSAEnumNetworkEvents 函数用于发现自上次调用此函数以来,指示的套接字发生了哪些网络事件。 它旨在与 WSAEventSelect 结合使用,后者将事件对象与一个或多个网络事件相关联。 当使用非零 lNetworkEvents 参数调用 WSAEventSelect 时,网络事件的记录将开始,并一直有效,直到将 lNetworkEvents 参数设置为零对 WSAEventSelect 进行另一次调用,或者直到调用 WSAAsyncSelect 为止。
WSAEnumNetworkEvents 仅报告通过 WSAEventSelect 指定的网络活动和错误。 请参阅 select 和 WSAAsyncSelect 的说明,了解这些函数如何报告网络活动和错误。
套接字的网络事件内部记录将复制到 lpNetworkEvents 引用的结构,然后清除内部网络事件记录。 如果 hEventObject 参数不是 NULL,则指示的事件对象也会重置。 Windows 套接字提供程序保证复制网络事件记录、清除网络事件记录和重置任何关联事件对象的操作都是原子的,因此,指定网络事件的下一次出现将导致事件对象设置。 如果此函数返回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 |
Library | Ws2_32.lib |
DLL | Ws2_32.dll |