Функция обратного вызова LPWSPASYNCSELECT (ws2spi.h)
Функция LPWSPAsyncSelect запрашивает уведомление о событиях на основе сообщений Windows о сетевых событиях для сокета.
Синтаксис
LPWSPASYNCSELECT Lpwspasyncselect;
int Lpwspasyncselect(
[in] SOCKET s,
[in] HWND hWnd,
[in] unsigned int wMsg,
[in] long lEvent,
[out] LPINT lpErrno
)
{...}
Параметры
[in] s
Дескриптор, определяющий сокет, для которого требуется уведомление о событии.
[in] hWnd
Дескриптор идентифицирует окно, которое должно получать сообщение при возникновении сетевого события.
[in] wMsg
Сообщение, отправляемое при возникновении сетевого события.
[in] lEvent
Битовая маска, задающая сочетание сетевых событий, в которых заинтересован клиент интерфейса поставщика сокетов Windows (SPI). Создается с помощью побитового оператора OR с любым из этих значений.
Значение | Значение |
---|---|
|
Выдает уведомление о готовности к чтению. |
|
Выдает уведомление о готовности к написанию. |
|
Выдает уведомление о поступлении данных OOB. |
|
Выдает уведомление о входящих подключениях. |
|
Выдает уведомление о завершенных подключениях. |
|
Выдает уведомление о закрытии сокета. |
|
Выдает уведомление об изменениях качества обслуживания (QoS). |
|
Зарезервировано. |
|
Выдает уведомление об изменении интерфейса маршрутизации для указанного назначения. |
|
Выдает уведомление об изменении локального списка адресов для семейства протоколов сокета. |
[out] lpErrno
Указатель на код ошибки. Дополнительные сведения см. в разделе Возвращаемое значение .
Возвращаемое значение
Возвращаемое значение равно нулю, если клиент Windows Sockets SPI успешно объявляет интерес к набору сетевых событий. В противном случае возвращается значение, SOCKET_ERROR, и в lpErrno доступен определенный код ошибки.
Код ошибки | Значение |
---|---|
Произошел сбой сетевой подсистемы. | |
Указывает, что один из указанных параметров был недопустимым, например, дескриптор окна, не ссылающийся на существующее окно, или указанный сокет находится в недопустимом состоянии. | |
Выполняется блокирующий вызов Windows Sockets или поставщик услуг по-прежнему обрабатывает функцию обратного вызова. | |
Дескриптор не является сокетом. |
Дополнительные коды ошибок, которые можно задать (в высоком слове lParam в сообщении) при получении сообщения в окне приложения, см. в примечаниях.
Комментарии
Эта функция используется для запроса на отправку поставщиком услуг сообщения Windows в окно клиента hWnd всякий раз, когда поставщик услуг обнаруживает какие-либо сетевые события, указанные аргументом lEvent . Поставщик услуг должен использовать функцию WPUPostMessage для публикации сообщения. Отправляемые сообщения задаются параметром wMsg . Сокет, для которого требуется уведомление, определяется по s.
Эта функция автоматически устанавливает сокеты в режим неблокировки, независимо от значения lEvent. Сведения о том, как вернуть сокет в режим блокировки, см. в разделе LPWSPIoctl .
Вызов LPWSPAsyncSelect для сокета отменяет все предыдущие LPWSPAsyncSelect или LPWSPEventSelect для того же сокета. Например, чтобы получать уведомления о чтении и записи, клиент SPI сокетов Windows должен вызвать LPWSPAsyncSelect с FD_READ и FD_WRITE, как показано ниже.
rc = WSPAsyncSelect(s, hWnd, wMsg, FD_READ | FD_WRITE, &error);
Невозможно указать разные сообщения для разных событий. Следующий код не будет работать. второй вызов отменяет эффекты первого, и единственной связью будет событие FD_WRITE, связанное с wMsg2.
// Incorrect example.
rc = WSPAsyncSelect(s, hWnd, wMsg1, FD_READ, &error);
rc = WSPAsyncSelect(s, hWnd, wMsg2, FD_WRITE, &error);
Чтобы отменить все уведомления (т. е. указать, что поставщик услуг не должен отправлять больше сообщений, связанных с сетевыми событиями в сокете), установите для параметра lEvent значение 0.
rc = WSPAsyncSelect(s, hWnd, 0, 0, &error);
Так как сокет LPWSPAccept'ed имеет те же свойства, что и сокет прослушивания, используемый для его принятия, любые события LPWSPAsyncSelect, заданные для сокета прослушивания, применяются к принятому сокету. Например, если прослушивающий сокет содержит события LPWSPAsyncSelect FD_ACCEPT, FD_READ и FD_WRITE, то любой сокет, принятый в этом сокете прослушивания, также будет иметь события FD_ACCEPT, FD_READ и FD_WRITE с тем же значением wMsg , которое используется для сообщений. Если требуются другие события wMsg или , клиент SPI сокетов Windows должен вызвать LPWSPAsyncSelect, передав принятый сокет и необходимые новые сведения.
Когда одно из назначенных сетевых событий происходит в указанных сокетах, поставщик услуг использует WPUPostMessage для отправки сообщения wMsg в окно hWnd клиента SPI windows Sockets. В отправленном сообщении аргумент wParam определяет сокет, в котором произошло сетевое событие. Низкое слово lParam указывает сетевое событие, которое произошло. Ниже приведены возможные коды сетевых событий.
Значение | Значение |
---|---|
FD_READ | Сокет готов к чтению |
FD_WRITE | Сокет готов к записи |
FD_OOB | Внеполосные данные готовы к чтению в сокетах |
FD_ACCEPT | Socket s готов принять новое входящее подключение |
FD_CONNECT | Подключение, которое было инициировано в сокетах, завершено |
FD_CLOSE | Подключение, определенное по сокетам, закрыто |
FD_QOS | Изменилось качество обслуживания, связанного с сокетами |
FD_GROUP_QOS | Зарезервировано для будущего использования с группами сокетов: изменилось качество обслуживания, связанного с группой сокетов, к которой принадлежит сокет. |
FD_ROUTING_INTERFACE_CHANGE | Изменен локальный интерфейс, который должен использоваться для отправки в указанное место назначения. |
FD_ADDRESS_LIST_CHANGE | Изменился список адресов семейства протоколов сокета, к которым может привязаться клиент SPI сокетов Windows. |
Высокое слово lParam содержит любой код ошибки (его можно извлечь с помощью макроса WSAGETSELECTERROR ). Код ошибки — любая ошибка, определенная в ws2spi.h
. В следующей таблице перечислены возможные коды ошибок для каждого сетевого события.
Событие: FD_CONNECT
Код ошибки | Значение |
---|---|
Адреса из заданного семейства адресов не могут использоваться с этим сокетом. | |
Попытка подключения была отклонена. | |
В настоящее время сеть недоступна с этого узла. | |
Недопустимый параметр namelen . | |
Сокет уже привязан к адресу. | |
Сокет уже подключен. | |
Больше нет доступных дескрипторов файлов. | |
Нет свободного места в буфере. Не удается подключить сокет. | |
Сокет не подключен. | |
Истекло время ожидания попытки подключения без установления подключения. |
Событие: FD_CLOSE
Код ошибки | Значение |
---|---|
Произошел сбой сетевой подсистемы. | |
Подключение было сброшено удаленной стороной. | |
Подключение было прервано из-за истечения времени ожидания или другого сбоя. |
Событие...: FD_ACCEPT, FD_ADDRESS_LIST_CHANGE, FD_GROUP_QOS, FD_OOB, FD_QOS, FD_READ, FD_WRITE
Код ошибки | Значение |
---|---|
Произошел сбой сетевой подсистемы. |
Событие: FD_ROUTING_INTERFACE_CHANGE
Код ошибки | Значение |
---|---|
Указанное назначение больше недоступно. | |
Произошел сбой сетевой подсистемы. |
Хотя LPWSPAsyncSelect можно вызывать с интересом к нескольким событиям, поставщик услуг выдает одно и то же сообщение Windows для каждого события.
Поставщик сокетов Windows 2 не должен постоянно заполнять клиент Windows Sockets SPI сообщениями для определенного сетевого события. После успешной публикации уведомления о конкретном событии в окне клиента SPI сокетов Windows никакие дополнительные сообщения для этого сетевого события не будут отправляться в окно клиента WINDOWS Sockets SPI до тех пор, пока клиент 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 публикация сообщений активируется на уровне. Это означает, что если вызывается процедура повторного включения и соответствующее условие по-прежнему выполняется после вызова, сообщение LPWSPAsyncSelect отправляется клиенту SPI windows Sockets.
События FD_QOS и FD_GROUP_QOS считаются запущенными по краю. Сообщение будет опубликовано ровно один раз при изменении QOS. Дальнейшие сообщения не будут выводиться, пока поставщик не обнаружит дальнейшее изменение в QOS или клиент Windows Sockets SPI не пересматривает QOS для сокета.
События 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.
Если какое-либо событие уже произошло при вызове клиентом SPI сокетов Windows LPWSPAsyncSelect или при вызове функции повторного включения, сообщение публикуется соответствующим образом. Например, рассмотрим следующую последовательность.
- Клиент WINDOWS Sockets SPI вызывает LPWSPListen.
- Запрос на подключение получен, но еще не принят.
- Клиент SPI сокетов Windows вызывает LPWSPAsyncSelect , указывая, что он хочет получать FD_ACCEPT сообщения для сокета. Из-за сохраняемости событий поставщик службы WinSock немедленно публикует FD_ACCEPT сообщение.
Событие FD_WRITE обрабатывается немного иначе. Сообщение FD_WRITE публикуется, когда сокет сначала подключается к LPWSPConnect (после FD_CONNECT, если также зарегистрирован) или принимается с помощью LPWSPAccept, а затем после того, как LPWSPSend или LPWSPSendTo завершается сбоем с WSAEWOULDBLOCK и буферное пространство становится доступным. Таким образом, клиент SPI-сокетов Windows может предположить, что отправка возможна, начиная с первого FD_WRITE сообщения и продлится до тех пор, пока отправка не вернет WSAEWOULDBLOCK. После такого сбоя клиент SPI сокетов Windows получит уведомление о том, что отправка снова возможна с помощью FD_WRITE сообщения.
Событие FD_OOB используется только в том случае, если сокет настроен для получения данных по отдельности. Если сокет настроен для получения внеполосных данных в строке, то внеполосные (ускоряемые) данные обрабатываются как обычные данные, и клиент WINDOWS Sockets SPI должен регистрировать интерес к событиям FD_READ, а не к событиям FD_OOB.
Код ошибки в сообщении FD_CLOSE указывает, было ли закрытие сокета корректно или прервано. Если код ошибки равен 0, закрытие было корректно. Если код ошибки — WSAECONNRESET, то виртуальный канал сокета был сброшен. Это относится только к сокетам, ориентированным на подключение, таким как SOCK_STREAM.
Сообщение FD_CLOSE публикуется при получении указания на закрытие виртуального канала, соответствующего сокету. С точки зрения TCP это означает, что FD_CLOSE отправляется, когда подключение переходит в состояния TIME WAIT или CLOSE WAIT. Это происходит из-за того, что удаленный конец выполняет LPWSPShutdown на стороне отправки или LPWSPCloseSocket. Правильно, чтобы FD_CLOSE публиковаться только после того, как все данные считываются из сокета.
В случае корректного закрытия поставщик услуг должен отправить FD_CLOSE сообщение, указывающее на закрытие виртуального канала только после считывания всех полученных данных. Оно не должно отправлять FD_READ сообщение, указывающее на это условие.
Сообщение FD_QOS или FD_GROUP_QOS публикуется при изменении любого поля в спецификации потока, связанной с сокетами, или в группе сокетов , к которой они принадлежат соответственно. Поставщик услуг должен обновить сведения о QOS, доступные клиенту через LPWSPIoctl , с помощью SIO_GET_QOS и (или) SIO_GET_GROUP_QOS.
Сообщение FD_ROUTING_INTERFACE_CHANGE публикуется, когда локальный интерфейс, который должен использоваться для достижения назначения, указанного в LPWSPIoctl , с SIO_ROUTING_INTERFACE_CHANGE изменения после выдачи такого IOCTL.
Сообщение FD_ADDRESS_LIST_CHANGE публикуется, когда список адресов, к которым клиент spi может привязать сокеты Windows, изменяется послевыдачи LPWSPIoctl с SIO_ADDRESS_LIST_CHANGE.
Ниже приведена сводка событий и условий для каждого асинхронного уведомления.
FD_READ
- Если вызывается LPWSPAsyncSelect , если в настоящее время доступны данные для получения.
- При поступлении данных, если FD_READ еще не опубликовано.
- После вызова LPWSPRecv или LPWSPRecvFrom (с MSG_PEEK или без него), если данные по-прежнему доступны для получения.
Если SO_OOBINLINE LPWSPSetSockOpt включен, данные включают как обычные, так и внештатные (OOB) данные в указанных выше экземплярах.
FD_WRITE
- Если вызывается LPWSPAsyncSelect , возможно ли LPWSPSend или LPWSPSendTo .
- После вызова LPWSPConnect или LPWSPAccept при установке подключения.
- После сбоя LPWSPSend или LPWSPSendTo с WSAEWOULDBLOCK, если LPWSPSend или LPWSPSendTo , скорее всего, завершится успешно.
- После LPWSPBind в сокете без подключения. FD_WRITE может произойти или не происходить в настоящее время (зависит от реализации). В любом случае сокет без подключения всегда доступен для записи сразу после LPWSPBind.
FD_OOB (допустимо только в том случае, если SO_OOBINLINE LPWSPSetSockOpt отключен (по умолчанию))
- При вызове LPWSPAsyncSelect , если в настоящее время доступны данные OOB для получения с флагом MSG_OOB.
- При поступлении данных OOB, если FD_OOB еще не опубликовано.
- После вызова LPWSPRecv или LPWSPRecvFrom с флагом MSG_OOB или без него, если данные OOB по-прежнему доступны для получения.
FD_ACCEPT
- Если вызывается LPWSPAsyncSelect , если в настоящее время доступен запрос на подключение для принятия.
- При поступлении запроса на подключение, если FD_ACCEPT еще не опубликовано.
- Если после вызова LPWSPAccept имеется другой запрос на подключение, который можно принять.
FD_CONNECT
- При вызове LPWSPAsyncSelect , если в настоящее время установлено подключение.
- После вызова LPWSPConnect при установке подключения (даже при немедленном завершении LPWSPConnect , как это обычно происходит с сокетом датаграммы), и даже при немедленном сбое).
- После вызова WSPJoinLeaf по завершении операции соединения.
- После подключения был вызван WSAConnect или WSPJoinLeaf с неблокирующим сокетом, ориентированным на подключение. Исходная операция была возвращена с определенной ошибкой WSAEWOULDBLOCK, но сетевая операция была выполнена. Независимо от того, завершается ли операция успешной или нет, когда результат определен, FD_CONNECT происходит. Клиент должен проверка код ошибки, чтобы определить, был ли результат успешным или неудачным.
FD_CLOSE (допустимо только для сокетов, ориентированных на подключение (например, SOCK_STREAM))
- При вызове LPWSPAsyncSelect , если подключение к сокету закрыто.
- После того как удаленная система инициировала корректное закрытие, когда данные в настоящее время недоступны для получения (если данные получены и ожидают чтения, когда удаленная система инициирует корректное закрытие, FD_CLOSE не доставляется до тех пор, пока не будут прочитаны все ожидающие данные).
- После того как локальная система инициирует корректное закрытие с помощью LPWSPShutdown и удаленная система ответила уведомлением об окончании данных (например, TCP FIN), если данные в настоящее время недоступны для получения.
- Когда удаленная система прервет подключение (например, отправлено TCP RST), и lParam будет содержать значение ошибки WSAECONNRESET.
FD_CLOSE не публикуется после вызова LPWSPCloseSocket .
FD_QOS
- При вызове LPWSPAsyncSelect , если QOS, связанный с сокетом, был изменен.
- После вызова LPWSPIoctl с SIO_GET_QOS при изменении QOS.
FD_GROUP_QOS
Зарезервировано для будущего использования с группами сокетов:
- При вызове LPWSPAsyncSelect , если группа QOS, связанная с сокетом, была изменена.
- После вызова LPWSPIoctl с SIO_GET_GROUP_QOS при изменении QOS группы.
FD_ROUTING_INTERFACE_CHANGE
- после вызова LPWSPIoctl с SIO_ROUTING_INTERFACE_CHANGE при изменении локального интерфейса, который должен использоваться для достижения назначения, указанного в IOCTL.
FD_ADDRESS_LIST_CHANGE
- после вызова LPWSPIoctl с SIO_ADDRESS_LIST_CHANGE при изменении списка локальных адресов, к которым может привязаться клиент SPI сокетов Windows.
Требования
Требование | Значение |
---|---|
Минимальная версия клиента | сборка Windows 10 20348 |
Минимальная версия сервера | сборка Windows 10 20348 |
Верхняя часть | ws2spi.h |
См. также раздел
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по