Поделиться через


Функция обратного вызова LPWWSPASYNCSELECT (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 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

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

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

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

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

Дополнительные сведения о дополнительных кодах ошибок, которые можно задать (в высоком слове lParam в сообщении) см. в при получении сообщения в окне приложения.

Замечания

Эта функция используется для запроса отправки поставщиком услуг сообщения Windows в окно клиента hWnd, когда поставщик услуг обнаруживает любые сетевые события, указанные аргументом lEvent. Поставщик услуг должен использовать функцию WPUPostMessage для публикации сообщения. Отправленное сообщение указывается параметром wMsg. Сокет, для которого требуется уведомление, определяется .

Эта функция автоматически устанавливает сокетов в режим неблокировки независимо от значения 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 значение нулю.

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 в окно клиента SPI Windows Sockets hWnd. В размещенном сообщении аргумент wParam определяет сокет, на котором произошло сетевое событие. Низкое слово lParam указывает сетевое событие, которое произошло. Возможные коды событий сети, которые могут быть указаны ниже.

Ценность Значение
FD_READ сокета готов к чтению
FD_WRITE Сокет готов к написанию
FD_OOB Внеполосные данные готовы к чтению сокета
FD_ACCEPT сокета готова принять новое входящее подключение
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

Код ошибки Значение
WSAEAFNOSUPPORT
Адреса в указанном семействе нельзя использовать с этим сокетом.
WSAECONNREFUSED
Попытка подключения была отклонена.
WSAENETUNREACH
Сеть не может быть достигнута из этого узла в настоящее время.
WSAEFAULT
Недопустимый параметр namelen.
WSAEINVAL
Сокет уже привязан к адресу.
WSAEISCONN
Сокет уже подключен.
WSAEMFILE
Больше дескрипторов файлов не доступны.
WSAENOBUFS
Буферное пространство недоступно. Не удается подключить сокет.
WSAENOTCONN
Сокет не подключен.
WSAETIMEDOUT
Попытайтесь подключиться без установления подключения.

Событие : FD_CLOSE

Код ошибки Значение
WSAENETDOWN
Сбой сетевой подсистемы.
WSAECONNRESET
Подключение было сброшено удаленной стороной.
WSAECONNABORTED
Подключение было прекращено из-за истечения времени ожидания или другого сбоя.

событие ...: FD_ACCEPT, FD_ADDRESS_LIST_CHANGE, FD_GROUP_QOS, FD_OOB, FD_QOS, FD_READ, FD_WRITE

Код ошибки Значение
WSAENETDOWN
Сбой сетевой подсистемы.

Событие : FD_ROUTING_INTERFACE_CHANGE

Код ошибки Значение
WSAENETUNREACH
Указанное назначение больше не доступно.
WSAENETDOWN
Сбой сетевой подсистемы.

Хотя LPWSPAsyncSelect можно вызывать с интересом к нескольким событиям, поставщик услуг выдает одно и то же сообщение Windows для каждого события.

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

Сетевое событие Повторное включение функции
FD_READ LPWSPRecv или LPWSPRecvFrom
FD_WRITE LPWSPSend или LPWSPSendTo
FD_OOB LPWSPRecv или LPWSPRecvFrom
FD_ACCEPT LPWSPAccept, если возвращен код ошибки WSATRY_AGAIN, указывающий, что функция условия возвращает CF_DEFER
FD_CONNECT НИКАКОЙ
FD_CLOSE НИКАКОЙ
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.

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

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

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

  1. Клиент SPI для Сокетов Windows вызывает LPWSPListen.
  2. Запрос подключения получен, но еще не принят.
  3. Клиент 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 используется только в том случае, если сокет настроен для получения данных вне диапазона отдельно. Если сокет настроен на получение внеполосных данных в строке, то внеполосные (ускоряемые) данные обрабатываются как обычные данные, а клиент SPI сокетов Windows должен зарегистрировать интерес к событиям 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

  1. При вызове LPWSPAsyncSelect, если доступны данные для получения.
  2. При поступлении данных, если FD_READ еще не размещены.
  3. После вызова LPWSPRecv или LPWSPRecvFrom (с MSG_PEEK или без нее), если данные по-прежнему доступны для получения.

Если включена LPWSPSetSockOpt SO_OOBINLINE, данные включают как обычные данные, так и данные вне диапазона (OOB) в указанных выше экземплярах.

FD_WRITE

  1. При вызове LPWSPAsyncSelect можно LPWSPSend или LPWSPSendTo.
  2. После вызова LPWSPConnect или LPWSPAccept при установке подключения.
  3. После LPWSPSend или LPWSPSendTo сбой с помощью WSAEWOULDBLOCK, если LPWSPSend или LPWSPSendTo, скорее всего, будут успешными.
  4. После LPWSPBind в сокете без подключения. FD_WRITE может или не возникать в настоящее время (зависит от реализации). В любом случае без подключения сокет всегда доступен для записи сразу после LPWSPBind.

FD_OOB (допустимо, только если LPWSPSetSockOpt SO_OOBINLINE отключен (по умолчанию))

  1. При вызове LPWSPAsyncSelect, если доступны данные OOB для получения с флагом MSG_OOB.
  2. При поступлении данных OOB, если FD_OOB еще не размещены.
  3. После вызова LPWSPRecv или LPWSPRecvFrom с флагом MSG_OOB или без него, если данные OOB по-прежнему доступны для получения.

FD_ACCEPT

  1. При вызове LPWSPAsyncSelect, если в настоящее время доступен запрос на подключение.
  2. При поступлении запроса на подключение, если FD_ACCEPT еще не опубликовано.
  3. После вызова LPWSPAccept, если есть еще один запрос на подключение, доступный для принятия.

FD_CONNECT

  1. При вызове LPWSPAsyncSelect, если установлено подключение.
  2. После вызова LPWSPConnect при установке подключения (даже если LPWSPConnect выполняется немедленно, как обычно с сокетом диаграммы данных), и даже при сбое сразу).
  3. После вызова WSPJoinLeaf после завершения операции соединения.
  4. После подключенияWSAConnectили WSPJoinLeaf вызывается с неблокирующим, ориентированным на подключение сокетом. Начальная операция возвращается с определенной ошибкой WSAEWOULDBLOCK, но сетевая операция прошла вперед. Будет ли операция успешно выполнена или нет, когда результат был определен, FD_CONNECT происходит. Клиент должен проверить код ошибки, чтобы определить, был ли результат успешной или неудачной.

FD_CLOSE (допустимо только для сокетов, ориентированных на подключение (например, SOCK_STREAM))

  1. При вызове LPWSPAsyncSelect, если подключение сокета было закрыто.
  2. После того, как удаленная система инициировала корректное закрытие, когда данные в настоящее время недоступны для получения (если данные были получены и ожидает чтения, когда удаленная система инициирует корректное закрытие, FD_CLOSE не доставляется до тех пор, пока все ожидающие данные не будут прочитаны).
  3. После того как локальная система инициирует корректное закрытие с LPWSPShutdown, а удаленная система ответила на уведомление конца данных (например, TCP FIN), когда данные в настоящее время недоступны для получения.
  4. При прерывании подключения удаленной системы (например, отправки TCP RST) и lParam будет содержать значение ошибки WSAECONNRESET.

FD_CLOSE не публикуется после вызова LPWSPCloseSocket.

FD_QOS

  1. При вызове LPWSPAsyncSelect, если QOS, связанный с сокетом, был изменен.
  2. После вызова LPWSPIoctl с SIO_GET_QOS при изменении QOS.

FD_GROUP_QOS

Зарезервировано для дальнейшего использования с группами сокетов:

  1. При вызове LPWSPAsyncSelect, если группа QOS, связанная с сокетом, была изменена.
  2. После вызова LPWSPIoctl с SIO_GET_GROUP_QOS при изменении QOS группы.

FD_ROUTING_INTERFACE_CHANGE

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

FD_ADDRESS_LIST_CHANGE

  1. после вызова LPWSPIoctl с SIO_ADDRESS_LIST_CHANGE при вызове списка локальных адресов, к которым может привязать клиент SPI сокетов Windows.

Требования

Требование Ценность
минимальные поддерживаемые клиентские Сборка Windows 10 20348
минимальный поддерживаемый сервер Сборка Windows 10 20348
заголовка ws2spi.h

См. также

функции обратного вызова LPWSPAsyncSelect