LPFN_RIOSEND回调函数 (mswsock.h)

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

语法

LPFN_RIOSEND LpfnRiosend;

BOOL LpfnRiosend(
  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

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

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 标志的情况下发出最后一个请求,从而导致最后一个请求的完成速度比其他请求慢得多。

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

RIO_MSG_DONT_NOTIFY

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

RIO_MSG_DEFER

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

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

注意

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

RequestContext

返回值

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

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

返回代码 说明
WSAEFAULT 系统尝试在调用中使用指针参数时检测到指针地址无效。 如果在将操作排队或调用之前,为参数中传递的任何 RIO_BUF 结构释放缓冲区标识符或释放缓冲区,则返回此错误。
WSAEINVAL 向该函数传递了无效参数。
如果 SocketQueue 参数无效、 Flags 参数包含的值对发送操作无效,或者完成队列的完整性受到损害,则返回此错误。 对于参数的其他问题,也可能会返回此错误。
WSAENOBUFS 无法分配足够的内存。 如果与 SocketQueue 参数关联的 I/O 完成队列已满,或者 I/O 完成队列是使用零个发送条目创建的,则返回此错误。
WSA_IO_PENDING 操作已成功启动,稍后将排队完成。

注解

应用程序可以使用 RIOSend 函数从完全包含在单个已注册缓冲区中的任何缓冲区发送网络数据。 pData 参数指向的 RIO_BUF 结构的 OffsetLength 成员确定要从缓冲区发送的网络数据。

与发送操作关联的缓冲区不得与另一个发送或接收操作同时使用。 缓冲区和缓冲区注册必须在发送操作期间保持有效。 这意味着,当某个请求已挂起时,不应将相同的PRIO_BUF传递给 RIOSend (Ex) 请求。 只有在完成正在进行的 RIOSend (Ex) 请求后,才应重复使用具有相同偏移量或不同偏移量和长度) 的相同PRIO_BUF (。 此外,当发送数据引用注册的缓冲区 (部分或整个缓冲区) 时,不得使用整个已注册缓冲区,直到发送完成。 这包括使用注册缓冲区的一部分进行接收操作或另一个发送操作。

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

注意

必须在运行时通过调用 WSAIoctl 函数并指定SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER操作码来获取指向 RIOSend 函数的函数指针。 传递给 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