LPFN_RIORECEIVE回调函数 (mswsock.h)

RIOReceive 函数在连接的已注册 I/O TCP 套接字或绑定的已注册 I/O UDP 套接字上接收网络数据,以便与 Winsock 注册的 I/O 扩展一起使用。

语法

LPFN_RIORECEIVE LpfnRioreceive;

BOOL LpfnRioreceive(
  RIO_RQ SocketQueue,
  PRIO_BUF pData,
  ULONG DataBufferCount,
  DWORD Flags,
  PVOID RequestContext
)
{...}

参数

SocketQueue

标识已连接的已注册 I/O TCP 套接字或绑定的已注册 I/O UDP 套接字的描述符。

pData

用于接收数据的已注册缓冲区部分的说明。

如果应用程序不需要在 UDP 数据报中接收数据有效负载,则对于绑定注册的 I/O UDP 套接字,此参数可能为 NULL。

DataBufferCount

一个数据缓冲区计数参数,指示是否在 pData 参数指向的缓冲区中接收数据。

如果 pData 为 NULL,则此参数应设置为零。 否则,此参数应设置为 1。

Flags

一组标志,用于修改 RIOReceive 函数的行为。

Flags 参数可以包含以下在头文件中定义的Mswsockdef.h选项的组合:

RIO_MSG_COMMIT_ONLY

将提交以前使用 RIO_MSG_DEFER 标志添加的请求。

设置 RIO_MSG_COMMIT_ONLY 标志时,不能指定其他标志。 设置RIO_MSG_COMMIT_ONLY标志时,pDataRequestContext 参数必须为 NULL,DataBufferCount 参数必须为零。

此标志通常偶尔会在发出多个请求后使用 RIO_MSG_DEFER 标志集。 这样就无需使用 RIO_MSG_DEFER 标志在没有 RIO_MSG_DEFER 标志的情况下发出最后一个请求,从而导致最后一个请求的完成速度比其他请求慢得多。

对 RIOReceive 函数的其他调用不同,当设置 RIO_MSG_COMMIT_ONLY 标志时,不需要序列化 对 RIOReceive 函数的调用。 对于单个RIO_RQ,可以在一个线程上使用 RIO_MSG_COMMIT_ONLY 调用 RIOReceive 函数,同时在另一个线程上调用 RIOReceive 函数。

RIO_MSG_DONT_NOTIFY

当请求完成插入到其完成队列时,请求不应触发 RIONotify 函数。

RIO_MSG_DEFER

不需要立即执行请求。 这会将请求插入请求队列,但它可能会触发或可能不会触发请求的执行。

数据接收可能会延迟,直到对在 SocketQueue 参数中传递的RIO_RQ发出接收请求,而不设置RIO_MSG_DEFER标志。 若要触发请求队列中所有接收的执行,请在不设置 RIO_MSG_DEFER 标志的情况下调用 RIOReceiveRIOReceiveEx 函数。

注意

无论是否设置了RIO_MSG_DEFER,接收请求都会根据 SocketQueue 参数中传递的RIO_RQ上的未完成 I/O 容量收费。

RIO_MSG_WAITALL

在发生以下事件之一之前, RIOReceive 函数不会完成:

  • 调用方在 pData 参数中提供的缓冲区段已完全满。
  • 该连接已关闭。
  • 请求已取消或发生错误。

UDP 套接字不支持此标志。

RequestContext

要与此接收操作关联的请求上下文。

返回值

如果未发生错误, RIOReceive 函数将返回 TRUE。 在这种情况下,接收操作已成功启动,完成操作已排队或操作已成功启动,稍后将排队完成。

值为 FALSE 表示函数失败,操作未成功启动,并且不会将完成指示排入队列。 可以通过调用 WSAGetLastError 函数来检索特定的错误代码。

返回代码 说明
WSAEFAULT 系统尝试在调用中使用指针参数时检测到指针地址无效。 如果在将操作排入队列或调用之前,为参数中传递的任何 RIO_BUF 结构释放缓冲区标识符或释放缓冲区,则返回此错误。
WSAEINVAL 向该函数传递了无效参数。
如果 SocketQueue 参数无效、 Flags 参数包含的值对接收操作无效,或者完成队列的完整性受到损害,则返回此错误。 对于参数的其他问题,也可以返回此错误。
WSAENOBUFS 无法分配足够的内存。 如果与 SocketQueue 参数关联的 I/O 完成队列已满,或者 I/O 完成队列创建的接收条目为零,则返回此错误。
WSA_OPERATION_ABORTED 在接收操作处于挂起状态时,该操作已被取消。 如果套接字在本地或远程关闭,或者在此套接字上执行 WSAIoctl 中的 SIO_FLUSH 命令,则返回此错误。

注解

应用程序可以使用 RIOReceive 函数将网络数据接收到完全包含在单个已注册缓冲区中的任何缓冲区中。 pData 参数指向的 RIO_BUF 结构的 OffsetLength 成员确定网络数据在缓冲区中的接收位置。

调用 RIOReceive 函数后,在 pData 参数中传递的缓冲区(包括 RIO_BUF 结构的 BufferId 成员中的 RIO_BUFFERID )在接收操作期间必须保持有效。

为了避免争用条件,不应在请求完成之前读取或写入与接收请求关联的缓冲区。 这包括使用缓冲区作为发送请求的源或另一个接收请求的目标。 未与任何接收请求关联的已注册缓冲区部分不包括在此限制中。

Flags 参数可用于影响为关联套接字指定的选项之外的 RIOReceive 函数调用的行为。 此函数的行为由与 SocketQueue 参数关联的套接字上设置的任何套接字选项和 Flags 参数中指定的值的组合决定。

注意

必须在运行时通过调用 WSAIoctl 函数并指定SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER操作码来获取指向 RIOReceive 函数的函数指针。 传递给 WSAIoctl 函数的输入缓冲区必须包含 WSAID_MULTIPLE_RIO,这是一个全局唯一标识符 (GUID) 其值标识 Winsock 注册的 I/O 扩展函数。 成功后, WSAIoctl 函数返回的输出包含指向 RIO_EXTENSION_FUNCTION_TABLE 结构的指针,该结构包含指向 Winsock 注册的 I/O 扩展函数的指针。 SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL 在 Ws2def.h 头文件中定义。 WSAID_MULTIPLE_RIO GUID 在 Mswsock.h 头文件中定义。

Windows Phone 8:Windows Phone 8 及更高版本上的 Windows Phone 应用商店应用支持此函数。

Windows 8.1Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更高版本的 Windows 应用商店应用支持此函数。

要求

要求
Header mswsock.h