Функция обратного вызова LPWSPEVENTSELECT (ws2spi.h)

Функция LPWSPEventSelect указывает объект события, связанный с предоставленным набором сетевых событий.

Синтаксис

LPWSPEVENTSELECT Lpwspeventselect;

int Lpwspeventselect(
  [in]  SOCKET s,
  [in]  WSAEVENT hEventObject,
  [in]  long lNetworkEvents,
  [out] LPINT lpErrno
)
{...}

Параметры

[in] s

Дескриптор, определяющий сокет.

[in] hEventObject

Дескриптор, определяющий объект события, связанный с предоставленным набором сетевых событий.

[in] lNetworkEvents

Битовая маска, задающая сочетание сетевых событий, в которых заинтересован клиент WINDOWS Sockets SPI. Создается с помощью побитового оператора OR с любым из этих значений.

Значение Значение
FD_READ
Выдает уведомление о готовности к чтению.
FD_WRITE
Выдает уведомление о готовности к записи.
FD_OOB
Выдает уведомление о поступлении данных OOB.
FD_ACCEPT
Выдает уведомление о входящих подключениях.
FD_CONNECT
Проблемы с уведомлением о завершении подключения.
FD_CLOSE
Выдает уведомление о закрытии сокета.
FD_QOS
Выдает уведомление об изменениях сокета (QoS).
FD_GROUP_QOS
Зарезервировано.
FD_ROUTING_INTERFACE_CHANGE
Выдает уведомление об изменениях интерфейса маршрутизации для указанных назначений.
FD_ADDRESS_LIST_CHANGE
Выдает уведомление об изменениях локального списка адресов для семейства адресов сокета.

[out] lpErrno

Указатель на код ошибки. Дополнительные сведения см. в разделе Возвращаемое значение .

Возвращаемое значение

Возвращаемое значение равно нулю, если клиент Windows Sockets SPI успешно определяет сетевые события и связанный объект события. В противном случае возвращается значение SOCKET_ERROR , а в lpErrno доступен определенный номер ошибки.

Код ошибки Значение
WSAENETDOWN
Произошел сбой сетевой подсистемы.
WSAEINVAL
Указывает, что один из указанных параметров был недопустимым или указанный сокет находится в недопустимом состоянии.
WSAEINPROGRESS
Выполняется блокировка вызова сокетов Windows или поставщик услуг по-прежнему обрабатывает функцию обратного вызова.
WSAENOTSOCK
Дескриптор не является сокетом.

Комментарии

Эта функция используется для указания объекта события hEventObject, который будет связан с выбранными сетевыми событиями lNetworkEvents. Сокет, для которого указан объект события, идентифицируется по s. Объект события задается при возникновении любого из назначенных сетевых событий.

LPWSPEventSelect работает аналогично LPWSPAsyncSelect. Разница заключается в действиях, выполняемых при возникновении назначенного сетевого события. В то время как WSPAsyncSelect вызывает отправку сообщения Windows Spi, указанного клиентом Windows Sockets SPI, LPWSPEventSelect задает связанный объект события и записывает возникновение этого события во внутреннюю запись сетевого события. Клиент WINDOWS Sockets SPI может использовать LPWSPEnumNetworkEvents для получения содержимого записи внутреннего сетевого события и таким образом определить, какие из назначенных сетевых событий произошли.

LPWSPEventSelect — это единственная функция, которая вызывает запись и извлечение сетевых действий и ошибок через LPWSPEnumNetworkEvents. См. описание LPWSPSelect и LPWSPAsyncSelect , чтобы узнать, как эти функции сообщают о сетевой активности и ошибках.

Эта функция автоматически устанавливает сокеты в режим неблокировки независимо от значения lNetworkEvents.

Выдача LPWSPEventSelect для сокета отменяет любой предыдущий выбор LPWSPAsyncSelect или LPWSPEventSelect для того же сокета и удаляет запись внутренних сетевых событий. Например, чтобы связать объект события как с чтением, так и с записью сетевых событий, клиент Windows Sockets SPI должен вызвать LPWSPEventSelect как с FD_READ, так и с FD_WRITE, как показано ниже.

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

Невозможно указать разные объекты событий для разных сетевых событий. Следующий код не будет работать. второй вызов отменяет эффекты первого, и единственной связью будет сетевое событие FD_WRITE, связанное с hEventObject2.

// Incorrect example.
rc = WSPEventSelect(s, hEventObject1, FD_READ);
rc = WSPEventSelect(s, hEventObject2, FD_WRITE);

Чтобы отменить связь и выбор сетевых событий в сокете, необходимо задать для параметра lNetworkEvents нулевое значение. В этом случае параметр hEventObject игнорируется.

rc = WSPEventSelect(s, hEventObject, 0);

Закрытие сокета с помощью LPWSPCloseSocket также отменяет связь и выбор сетевых событий, указанных в LPWSPEventSelect для сокета. Однако клиент Windows Sockets SPI по-прежнему должен вызывать WSACloseEvent , чтобы явно закрыть объект события и освободить все ресурсы.

Так как сокет LPWSPAccept'ed имеет те же свойства, что и сокет прослушивания, используемый для его принятия, любой набор LPWSPEventSelect association and network events selection для сокета прослушивания применяется к принятому сокету. Например, если сокет прослушивания имеет связь LPWSPEventSelecthEventObject с FD_ACCEPT, FD_READ и FD_WRITE, то любой сокет, принятый в этом сокете прослушивания, также будет иметь FD_ACCEPT, FD_READ и FD_WRITE сетевые события, связанные с тем же hEventObject. Если требуются другие события hEventObject или сетевые события, клиент WINDOWS Sockets SPI должен вызвать LPWSPEventSelect, передав принятый сокет и необходимые новые сведения.

После успешной записи возникновения сетевого события и передачи сигнала связанному объекту события дальнейшие действия для этого сетевого события не выполняются до тех пор, пока клиент Windows Sockets SPI не вызовет функцию, которая неявно повторно включает настройку этого сетевого события и сигнализирует о связанном объекте события.

Сетевое событие Повторное включение функции
FD_READ LPWSPRecv или LPWSPRecvFrom
FD_WRITE LPWSPSend или LPWSPSendTo
FD_OOB LPWSPRecv или LPWSPRecvFrom
FD_ACCEPT LPWSPAccept, если возвращенный код ошибки не WSATRY_AGAIN указывающий, что функция условия вернула CF_DEFER
FD_CONNECT None
FD_CLOSE None
FD_QOS LPWSPIoctl с SIO_GET_QOS
FD_GROUP_QOS Зарезервировано для использования в будущем с группами сокетов: LPWSPIoctl с SIO_GET_GROUP_QOS
FD_ROUTING_INTERFACE_CHANGE LPWSPIoctl с командой SIO_ROUTING_INTERFACE_CHANGE
FD_ADDRESS_LIST_CHANGE LPWSPIoctl с командой SIO_ADDRESS_LIST_CHANGE

Любой вызов процедуры повторного включения , даже сбой, приводит к повторному включению записи и сигнализации для соответствующего сетевого события и объекта события соответственно.

Для FD_READ, FD_OOB и FD_ACCEPT сетевых событий запись сетевых событий и сигнализация объектов событий активируются на уровне. Это означает, что если вызывается подпрограмма повторного включения и соответствующее условие сети по-прежнему остается действительным после вызова, сетевое событие записывается и соответствующий объект события получает сигнал. Это позволяет клиенту Windows Sockets SPI управлять событиями, а также не беспокоиться о количестве данных, поступающих в любой момент времени. Рассмотрим следующую последовательность.

  1. Поставщик услуг получает 100 байт данных в сокетах, записывает сетевое событие FD_READ и сообщает связанному объекту события.
  2. Клиент Windows Sockets SPI не может WSPRecv(s, buffptr, 50, 0) считать 50 байт.
  3. Поставщик услуг записывает сетевое событие FD_READ и снова передает сигнал связанному объекту события, так как данные еще не прочитаны.

При использовании этой семантики клиенту SPI сокетов Windows не нужно считывать все доступные данные в ответ на сетевое событие FD_READ. Скорее, один LPWSPRecv в ответ на каждое сетевое событие FD_READ является подходящим.

События FD_QOS и FD_GROUP_QOS считаются активированными по краям. Сообщение будет опубликовано ровно один раз при изменении качества обслуживания (QOS). Дальнейшие указания не будут выдаваться до тех пор, пока поставщик услуг не обнаружит дальнейшее изменение в QOS или клиент Windows Sockets SPI не пересматривает качество обслуживания для сокета.

События FD_ROUTING_INTERFACE_CHANGE и FD_ADDRESS_LIST_CHANGE также считаются активированными по краям . Сообщение будет опубликовано ровно один раз, когда изменение произойдет после того, как клиент Windows Sockets SPI запросит уведомление путем выдачи WSAIoctl с SIO_ROUTING_INTERFACE_CHANGE или SIO_ADDRESS_LIST_CHANGE соответствующим образом. Дальнейшие сообщения не будут выдаваться до тех пор, пока клиент WINDOWS Sockets SPI повторно не выпустит IOCTL и не будет обнаружено другое изменение после выдачи IOCTL.

Если сетевое событие уже произошло, когда клиент Windows Sockets SPI вызывает LPWSPEventSelect или при вызове функции повторного включения, то сетевое событие записывается и соответствующий объект события подается соответствующим образом. Например, рассмотрим следующую последовательность.

  1. Клиент Windows Sockets SPI вызывает LPWSPListen.
  2. Запрос на подключение получен, но еще не принят.
  3. Клиент Windows Sockets SPI вызывает LPWSPEventSelect , указывая, что он заинтересован в сетевом событии FD_ACCEPT для сокета. Поставщик услуг записывает сетевое событие FD_ACCEPT и немедленно передает сигнал связанному объекту события.

Сетевое событие FD_WRITE обрабатывается немного иначе. Сетевое событие FD_WRITE записывается, когда сокет сначала подключается к LPWSPConnect или принимается с помощью LPWSPAccept, а затем после сбоя LPWSPSend или LPWSPSendTo с WSAEWOULDBLOCK и буферное пространство становится доступным. Таким образом, клиент WINDOWS Sockets SPI может предполагать, что отправка возможна начиная с первого параметра сетевого события FD_WRITE и длится до тех пор, пока отправка не вернет WSAEWOULDBLOCK. После такого сбоя клиент WINDOWS Sockets SPI обнаружит, что отправка снова возможна при записи сетевого события FD_WRITE и сигнале связанного объекта события.

Сетевое событие FD_OOB используется только в том случае, если сокет настроен для получения данных по отдельности. Если сокет настроен на получение данных вне диапазона по сети, то внеполосные (ускоряемые) данные обрабатываются как обычные данные, а клиент WINDOWS Sockets SPI должен регистрировать интерес и получать FD_READ сетевое событие, а не FD_OOB сетевое событие. Клиент SPI сокетов Windows может задать или проверить способ обработки данных вне диапазона с помощью LPWSPSetSockOpt или LPWSPGetSockOpt для параметра SO_OOBINLINE.

Код ошибки в сетевом событии FD_CLOSE указывает, было ли закрытие сокета корректно или прервано. Если код ошибки равен 0, то закрытие было корректно; Если код ошибки — WSAECONNRESET, то виртуальный канал сокета был сброшен. Это относится только к сокетам, ориентированным на подключение, таким как SOCK_STREAM.

Сетевое событие FD_CLOSE записывается при получении указания закрытия для виртуального канала, соответствующего сокету. С точки зрения TCP это означает, что FD_CLOSE записывается, когда подключение переходит в состояния FIN WAIT или CLOSE WAIT. Это результат удаленного выполнения LPWSPShutdown на стороне отправки или LPWSPCloseSocket.

Поставщики услуг должны записывать только сетевое событие FD_CLOSE, чтобы указать на закрытие виртуального канала; он не должен записывать сетевое событие FD_READ, чтобы указать это условие.

Сетевое событие FD_QOS или FD_GROUP_QOS записывается при изменении любого поля в спецификации потока, связанной с сокетами или группой сокетов , к которой они принадлежат соответственно. Это изменение должно быть доступно клиентам SPI сокетов Windows с помощью функции LPWSPIoctl с SIO_GET_QOS и (или) SIO_GET_GROUP_QOS для получения текущего QOS для сокетов или для группы сокетов, к которой принадлежит соответственно.

Сетевое событие FD_ROUTING_INTERFACE_CHANGE записывается, когда локальный интерфейс, который должен использоваться для достижения назначения, указанного в WSAIoctl , с SIO_ROUTING_INTERFACE_CHANGE изменениями после выдачи такого IOCTL.

Сетевое событие FD_ADDRESS_LIST_CHANGE записывается, когда список адресов семейства протоколов сокетов, к которым клиент WINDOWS Sockets SPI может привязаться , изменяется послевыдачи WSAIoctl с SIO_ADDRESS_LIST_CHANGE.

Требования

Требование Значение
Минимальная версия клиента сборка Windows 10 20348
Минимальная версия сервера сборка Windows 10 20348
Верхняя часть ws2spi.h

См. также раздел

LPWSPEnumNetworkEvents