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


функция обратного вызова LPFN_RIORECEIVEEX (mswsock.h)

Функция RIOReceiveEx получает сетевые данные в подключенном зарегистрированном сокете TCP ввода-вывода или привязанном зарегистрированном сокете UDP ввода-вывода с дополнительными параметрами для использования с зарегистрированными расширениями ввода-вывода Winsock.

Синтаксис

LPFN_RIORECEIVEEX LpfnRioreceiveex;

int LpfnRioreceiveex(
                                                                                                                     RIO_RQ SocketQueue,
                                                                                                                     PRIO_BUF pData,
                                                                                                                     ULONG DataBufferCount,
                                                                                                                     PRIO_BUF pLocalAddress,
                                                                                                                     PRIO_BUF pRemoteAddress,
                                                                                                                     PRIO_BUF pControlContext,
                                                                                                                     PRIO_BUF pFlags,
                                                                                                                     DWORD Flags,
                                                                                                                     PVOID RequestContext
)
{...}

Параметры

SocketQueue

Дескриптор, который идентифицирует подключенный зарегистрированный сокет UDP ввода-вывода или связанный зарегистрированный сокет UDP ввода-вывода.

pData

Описание части зарегистрированного буфера, в которой будут приниматься данные.

Этот параметр может иметь значение NULL для привязанного зарегистрированного сокета UDP ввода-вывода, если приложению не требуется получать полезные данные в датаграмме UDP.

DataBufferCount

Параметр счетчика буфера данных, указывающий, должны ли данные быть получены в буфере, на который указывает параметр pData .

Этот параметр должен быть равен нулю, если pData имеет значение NULL. В противном случае этому параметру следует задать значение 1.

pLocalAddress

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

Этот параметр может иметь значение NULL , если приложение не хочет получать локальный адрес. Если этот параметр не равен NULL, сегмент буфера должен быть не ниже размера SOCKADDR_INET структуры.

pRemoteAddress

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

Этот параметр может иметь значение NULL , если приложение не хочет получать удаленный адрес. Если этот параметр не равен NULL, сегмент буфера должен быть не ниже размера SOCKADDR_INET структуры.

pControlContext

Срез буфера, который после завершения будет содержать дополнительные сведения об операции получения.

Этот параметр может иметь значение NULL , если приложение не хочет получать дополнительные сведения об элементе управления.

pFlags

Flags

Набор флагов, которые изменяют поведение функции RIOReceiveEx .

Параметр Flags может содержать сочетание следующих параметров, определенных в файле заголовка Mswsockdef.h :

RIO_MSG_COMMIT_ONLY

Предыдущие запросы, добавленные с флагом RIO_MSG_DEFER , будут зафиксированы.

Если установлен флаг RIO_MSG_COMMIT_ONLY , другие флаги не могут быть указаны. Если флаг RIO_MSG_COMMIT_ONLY установлен, аргументы pData, pLocalAddress, pRemoteAddress, pControlContext, pFlags и RequestContext должны иметь значение NULL, а аргумент DataBufferCount должен быть равен нулю.

Этот флаг обычно используется иногда после того, как несколько запросов были выданы с набором флага RIO_MSG_DEFER . Это устраняет необходимость при использовании флага RIO_MSG_DEFER для выполнения последнего запроса без флага RIO_MSG_DEFER , что приводит к тому, что последний запрос выполняется гораздо медленнее, чем другие запросы.

В отличие от других вызовов функции RIOReceiveEx , при установке флага RIO_MSG_COMMIT_ONLY вызовы функции RIOReceiveEx не нужно сериализовать. Для одного RIO_RQ функцию RIOReceiveEx можно вызвать с помощью RIO_MSG_COMMIT_ONLY в одном потоке при вызове функции RIOReceiveEx в другом потоке.

RIO_MSG_DONT_NOTIFY

Запрос не должен запускать функцию RIONotify при вставке завершения запроса в очередь завершения.

RIO_MSG_DEFER

Запрос не нужно выполнять немедленно. При этом запрос будет вставлен в очередь запросов, но он может вызвать или не запустить выполнение запроса.

Прием данных может быть отложен до тех пор, пока запрос на получение не будет выполнен в RIO_RQ , переданном в параметре SocketQueue без установленного флага RIO_MSG_DEFER . Чтобы активировать выполнение для всех приемов в очереди запросов, вызовите функцию RIOReceive или RIOReceiveEx без установленного флага RIO_MSG_DEFER .

Примечание

Плата за запрос на получение взимается из-за неоплаченной емкости ввода-вывода в RIO_RQ , переданной в параметре SocketQueue , независимо от того, задано ли RIO_MSG_DEFER .

RIO_MSG_WAITALL

Функция RIOReceiveEx не завершится, пока не произойдет одно из следующих событий:

  • Срез буфера, предоставленный вызывающим объектом в параметре pData , полностью заполнен.
  • Соединение было закрыто.
  • Запрос был отменен или произошла ошибка.

Этот флаг не поддерживается для сокетов датаграмм или сокетов без подключения, ориентированных на сообщения.

RequestContext

Контекст запроса, связанный с этой операцией получения.

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

Если ошибки не произошло, функция RIOReceiveEx возвращает значение TRUE. В этом случае операция получения успешно инициирована, и завершение будет уже поставлено в очередь или операция успешно запущена, а завершение будет помещено в очередь позже.

Значение FALSE указывает, что функция завершилась сбоем, операция не была успешно инициирована, и индикатор завершения не будет помещен в очередь. Определенный код ошибки можно получить, вызвав функцию WSAGetLastError .

Код возврата Описание
WSAEFAULT Система обнаружила недопустимый адрес указателя при попытке использовать аргумент указателя в вызове. Эта ошибка возвращается, если идентификатор буфера отменяется или буфер освобождается для любой из RIO_BUF структур, передаваемых в параметрах перед постановкой в очередь или вызовом операции.
WSAEINVAL В функцию передан недопустимый параметр.
Эта ошибка возвращается, если параметр SocketQueue недопустим, параметр dwFlags содержит значение, недопустимое для операции получения, или целостность очереди завершения была скомпрометирована. Эта ошибка также может быть возвращена для других проблем с параметрами.
WSAENOBUFS Не удалось выделить достаточный объем памяти. Эта ошибка возвращается, если очередь завершения ввода-вывода, связанная с параметром SocketQueue , заполнена или очередь завершения ввода-вывода была создана с нулевыми записями получения.
WSA_OPERATION_ABORTED Операция была отменена в ожидании операции получения. Эта ошибка возвращается, если сокет закрыт локально или удаленно или выполняется команда SIO_FLUSH в WSAIoctl .

Комментарии

Приложение может использовать функцию RIOReceiveEx для получения сетевых данных в любой буфер, полностью содержащийся в одном зарегистрированном буфере. Элементы Offset и Length структуры RIO_BUF , на которые указывает параметр pData, определяют место получения сетевых данных в буфере.

После вызова функции RIOReceiveEx буфер, передаваемый в параметре pData , включая RIO_BUFFERID в элементе BufferId структуры RIO_BUF , должен оставаться действительным в течение операции получения.

Чтобы избежать условий гонки, буфер, связанный с запросом на получение, не следует читать или записывать до завершения запроса. Сюда входит использование буфера в качестве источника для запроса на отправку или назначения для другого запроса на получение. Части зарегистрированного буфера, не связанные с каким-либо запросом на получение, не включаются в это ограничение.

Параметр pLocalAddress можно использовать для получения локального адреса, по которому были получены данные. Параметр pRemoteAddress можно использовать для получения удаленного адреса, с которого были получены данные. Локальные и удаленные адреса возвращаются в виде SOCKADDR_INET структур. В результате элемент LengthRIO_BUF , на который указывают параметры pLocalAddress или pRemoteAddress , должен быть равен или больше размера структуры SOCKADDR_INET .

В следующей таблице перечислены различные варианты использования данных элемента управления, доступных для использования со сведениями об элементах управления в элементе pControlContext .

Протокол cmsg_level cmsg_type Описание
IPv4 IPPROTO_IP IP_ORIGINAL_ARRIVAL_IF Получает исходный интерфейс прибытия IPv4, в котором был получен пакет для сокетов датаграмм. Эти управляющие данные используются брандмауэрами, когда туннель Teredo, 6to4 или ISATAP используется для обхода NAT IPv4.
Элемент cmsg_data[] — это ULONG, содержащий IF_INDEX, определенный в файле заголовка ifdef.h .
Дополнительные сведения см. в разделе Параметры сокета IPPROTO_IP для параметра сокета IP_ORIGINAL_ARRIVAL_IF.
IPv4 IPPROTO_IP IP_PKTINFO Указывает или получает сведения о пакете.
Дополнительные сведения см. в разделе Параметры сокета IPPROTO_IP для параметра сокета IP_PKTINFO.
IPv6 IPPROTO_IPV6 IPV6_DSTOPTS Указывает и получает параметры назначения.
IPv6 IPPROTO_IPV6 IPV6_HOPLIMIT Указывает ограничение прыжков и их получение.
Дополнительные сведения см. в разделе Параметры сокета IPPROTO_IPV6 для параметра сокета IPV6_HOPLIMIT.
IPv6 IPPROTO_IPV6 IPV6_HOPOPTS Задает и получает параметры перехода за прыжком.
IPv6 IPPROTO_IPV6 IPV6_NEXTHOP Указывает адрес следующего прыжка.
IPv6 IPPROTO_IPV6 IPV6_PKTINFO Указывает или получает сведения о пакете.
Дополнительные сведения см. в разделе Параметры сокета IPPROTO_IPV6 для параметра сокета IPV6_PKTINFO.
IPv6 IPPROTO_IPV6 IPV6_RTHDR Задает/получает заголовок маршрутизации.

Данные элемента управления состоят из одного или нескольких объектов данных управления, каждый из которых начинается со структуры WSACMSGHDR , определенной следующим образом:

} WSACMSGHDR;

Ниже перечислены элементы структуры WSACMSGHDR .

Термин Описание
cmsg_len Число байтов данных, начиная с начала WSACMSGHDR и до конца данных (за исключением байтов заполнения, которые могут следовать за данными).
cmsg_level Протокол, который является источником сведений об элементе управления.
cmsg_type Тип сведений об управлении для конкретного протокола.

Параметр Flags можно использовать для влияния на поведение вызова функции RIOReceiveEx за пределами параметров, указанных для связанного сокета. Поведение этой функции определяется сочетанием всех параметров сокета, заданных в сокете, связанном с параметром SocketQueue, и значениями, указанными в параметре Flags .

Примечание

Указатель функции на функцию RIOReceiveEx должен быть получен во время выполнения путем вызова функции WSAIoctl с указанным SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER кодом операции. Входной буфер, передаваемый в функцию WSAIoctl , должен содержать WSAID_MULTIPLE_RIO, глобальный уникальный идентификатор (GUID), значение которого определяет функции расширения операций ввода-вывода, зарегистрированные в Winsock. При успешном выполнении выходные данные, возвращаемые функцией WSAIoctl , содержат указатель на структуру RIO_EXTENSION_FUNCTION_TABLE , содержащую указатели на зарегистрированные функции расширения ввода-вывода Winsock. SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL определяется в файле заголовка Ws2def.h. GUID WSAID_MULTIPLE_RIO определяется в файле заголовка Mswsock.h .

Windows Phone 8. Эта функция поддерживается для приложений Магазина Windows Phone на Windows Phone 8 и более поздних версиях.

Windows 8.1 и Windows Server 2012 R2. Эта функция поддерживается для приложений Магазина Windows на Windows 8.1, Windows Server 2012 R2 и более поздних версиях.

Требования

Требование Значение
Заголовок mswsock.h