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 Sockets 1.1 呼叫正在進行中,或者服務提供者仍在處理回呼函式。 | |
描述項不是套接字。 | |
lpNetworkEvents 參數不是使用者位址空間的有效部分。 |
備註
WSAEnumNetworkEvents 函式可用來探索自此函式最後一次叫用之後,所指示套接字發生的網路事件。 它適用於與 WSAEventSelect 搭配使用,其會將事件物件與一或多個網路事件產生關聯。 當使用非零 lNetworkEvents 參數呼叫 WSAEventSelect 時,網路事件的記錄就會開始,直到對 WSAEventSelect 進行另一個呼叫,並將 lNetworkEvents 參數設定為零,或直到呼叫 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 |