Функция 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, который связывает объект события с одним или несколькими сетевыми событиями. Запись сетевых событий начинается при вызове WSAEventSelect с ненулевым параметром lNetworkEvents и остается в силе до тех пор, пока не будет выполнен другой вызов WSAEventSelect с параметром lNetworkEvents , равным нулю, или до тех пор, пока не будет выполнен вызов WSAsyncSelect.
WSAEnumNetworkEvents сообщает только о сетевой активности и ошибках, назначенных с помощью WSAEventSelect. Ознакомьтесь с описаниями select и WSAsyncSelect , чтобы узнать, как эти функции сообщают о сетевой активности и ошибках.
Внутренняя запись сокета о сетевых событиях копируется в структуру, на которую ссылается lpNetworkEvents, после чего запись внутренних сетевых событий очищается. Если параметр hEventObject не равен NULL, указанный объект события также сбрасывается. Поставщик сокетов Windows гарантирует, что операции копирования записи сетевого события, ее очистки и сброса любого связанного объекта события являются атомарными, так что следующее возникновение назначенного сетевого события приведет к настройке объекта события. В случае, если эта функция возвращает SOCKET_ERROR, связанный объект события не сбрасывается, а запись сетевых событий не очищается.
Элемент lNetworkEvents структуры WSANETWORKEVENTS указывает, какое из FD_XXX сетевых событий произошло. Массив iErrorCode используется для хранения любых связанных кодов ошибок с индексом массива, соответствующим положению битов событий в lNetworkEvents. Для индексирования массива iErrorCode можно использовать такие идентификаторы, как FD_READ_BIT и FD_WRITE_BIT. Обратите внимание, что заданы только те элементы массива 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 Windows Phone 8 и более поздних версий.
Windows 8.1 и Windows Server 2012 R2. Эта функция поддерживается для приложений Магазина Windows в Windows 8.1, Windows Server 2012 R2 и более поздних версий.
Требования
Требование | Значение |
---|---|
Минимальная версия клиента | Windows 8.1, Windows Vista [классические приложения | Приложения UWP] |
Минимальная версия сервера | Windows Server 2003 [классические приложения | Приложения UWP] |
Целевая платформа | Windows |
Header | winsock2.h |
Библиотека | Ws2_32.lib |
DLL | Ws2_32.dll |