SIO_IDEAL_SEND_BACKLOG_QUERY控制代码
说明
SIO_IDEAL_SEND_BACKLOG_QUERY控制代码检索基础连接的理想发送积压工作 (ISB) 值。
若要执行此操作,请使用以下参数调用 WSAIoctl 或 WSPIoctl 函数。
int WSAIoctl(
(socket) s, // descriptor identifying a socket
SIO_IDEAL_SEND_BACKLOG_QUERY, // dwIoControlCode
NULL, // lpvInBuffer
0, // cbInBuffer
(LPVOID) lpvOutBuffer, // output buffer
(DWORD) cbOutBuffer, // size of output buffer
(LPDWORD) lpcbBytesReturned, // number of bytes returned
(LPWSAOVERLAPPED) lpOverlapped, // OVERLAPPED structure
(LPWSAOVERLAPPED_COMPLETION_ROUTINE) lpCompletionRoutine, // completion routine
);
int WSPIoctl(
(socket) s, // descriptor identifying a socket
SIO_IDEAL_SEND_BACKLOG_QUERY, // dwIoControlCode
NULL, // lpvInBuffer
0, // cbInBuffer
(LPVOID) lpvOutBuffer, // output buffer
(DWORD) cbOutBuffer, // size of output buffer
(LPDWORD) lpcbBytesReturned, // number of bytes returned
(LPWSAOVERLAPPED) lpOverlapped, // OVERLAPPED structure
(LPWSAOVERLAPPED_COMPLETION_ROUTINE) lpCompletionRoutine, // completion routine
(LPWSATHREADID) lpThreadId, // a WSATHREADID structure
(LPINT) lpErrno // a pointer to the error code.
);
参数
S
标识套接字的描述符。
dwIoControlCode
操作的控制代码。 对此操作使用 SIO_IDEAL_SEND_BACKLOG_QUERY 。
lpvInBuffer
指向输入缓冲区的指针。 此参数未用于此操作。
cbInBuffer
输入缓冲区的大小(以字节为单位)。 此参数未用于此操作。
lpvOutBuffer
指向输出缓冲区的指针。 如果 lpOverlapped 和 lpCompletionRoutine 参数为 NULL,则此参数应指向 ULONG 数据类型。
cbOutBuffer
输出缓冲区的大小(以字节为单位)。 此参数必须至少为 ULONG 数据类型的大小。
lpcbBytesReturned
指向变量的指针,该变量接收存储在输出缓冲区中的数据的大小(以字节为单位)。
如果输出缓冲区太小,则调用失败, WSAGetLastError 返回 WSAEINVAL, lBytesReturned 参数指向 DWORD 值零。
如果 lpOverlapped 为 NULL,则成功调用时返回的 lpcbBytesReturned 参数指向的 DWORD 值不能为零。
如果对于重叠套接字, lpOverlapped 参数不是 NULL ,则将启动无法立即完成的操作,并在以后的时间指示完成。 返回的 lpcbBytesReturned 参数指向的 DWORD 值可能为零,因为在重叠操作完成之前无法确定存储的数据的大小。 当操作完成时发出相应的完成方法信号时,可以检索最终完成状态。
lpvOverlapped
指向 WSAOVERLAPPED 结构的指针。
如果套接字 是在 不使用重叠属性的情况下创建的,则忽略 lpOverlapped 参数。
如果 已 使用重叠属性打开,并且 lpOverlapped 参数不是 NULL,则该操作将作为重叠 (异步) 操作执行。 在这种情况下, lpOverlapped 参数必须指向有效的 WSAOVERLAPPED 结构。
对于重叠操作, WSAIoctl 或 WSPIoctl 函数将立即返回,并在操作完成时发出相应的完成方法的信号。 否则,函数在操作完成或发生错误之前不会返回。
lpCompletionRoutine
类型:_In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
指向完成操作时调用的完成例程的指针, (忽略非重叠套接字) 。
lpThreadId
指向 WSATHREADID 结构的指针,供提供程序在后续调用 WPUQueueApc 时使用。 在 WPUQueueApc 函数返回之前,提供程序应存储引用的 WSATHREADID 结构 (而不是指向同一) 的指针。
注意 此参数仅适用于 WSPIoctl 函数。
lpErrno
指向错误代码的指针。
注意 此参数仅适用于 WSPIoctl 函数。
返回值
如果操作成功完成, WSAIoctl 或 WSPIoctl 函数将返回零。
如果操作失败或挂起, WSAIoctl 或 WSPIoctl 函数将返回 SOCKET_ERROR。 若要获取扩展错误信息,请调用 WSAGetLastError。
错误代码 | 含义 |
---|---|
WSA_IO_PENDING | 已成功启动重叠操作,稍后将指示完成。 |
WSA_OPERATION_ABORTED | 由于套接字关闭或执行 SIO_FLUSH IOCTL 命令,因此取消了重叠操作。 |
WSAEFAULT | lpvInBuffer、lpvoutBuffer、lBytesReturned、lpOverlapped 或 lpCompletionRoutine 参数并不完全包含在用户地址空间的有效部分。 |
WSAEINPROGRESS | 回调正在进行时调用 函数。 |
WSAEINTR | 阻止操作中断。 |
WSAEINVAL | dwIoControlCode 参数不是有效的命令,或者指定的输入参数不可接受,或者命令不适用于指定的套接字类型。 如果 cbOutBuffer 参数小于 ULONG 数据类型的大小,则返回此错误。 |
WSAENETDOWN | 网络子系统发生故障。 |
WSAENOPROTOOPT | 指定协议不支持套接字选项。 |
WSAENOTCONN | 套接字未连接。 |
WSAENOTSOCK | 描述符 s 不是套接字。 |
WSAEOPNOTSUPP | 不支持指定的 IOCTL 命令。 如果传输提供程序不支持 SIO_IDEAL_SEND_BACKLOG_QUERY IOCTL,则返回此错误。 在数据报套接字上尝试使用 SIO_IDEAL_SEND_BACKLOG_QUERY IOCTL 时,也会返回此错误。 |
备注
SIO_IDEAL_SEND_BACKLOG_QUERY IOCTL 在 Windows Server 2008、具有 Service Pack 1 的 Windows Vista (SP1) 以及更高版本的操作系统上受支持。
使用 Windows 套接字通过 TCP 连接发送数据时,请务必在 TCP 中 (发送但尚未确认) 保留足够的未完成数据量,以实现最高的吞吐量。 为 TCP 连接实现最佳吞吐量而未完成的数据量的理想值称为 (ISB) 大小的理想发送积压工作。 ISB 值是 TCP 连接的带宽延迟乘积和接收方播发接收窗口 (的函数,部分是网络) 拥塞量。
每个连接的 ISB 值可从 Windows Server 2008、Windows Vista SP1 和更高版本的操作系统中的 TCP 协议实现中获取。 当连接的 ISB 值动态更改时,应用程序可以使用 SIO_IDEAL_SEND_BACKLOG_QUERY IOCTL 来获取通知。
在 Windows Server 2008 SP1 的 Windows Vista 和更高版本的操作系统上,处于连接状态的面向流的套接字支持 SIO_IDEAL_SEND_BACKLOG_CHANGE 和 SIO_IDEAL_SEND_BACKLOG_QUERY IOCTL。
TCP 连接的 ISB 值的范围理论上可以介于 0 到最大 16 兆字节之间。
SIO_IDEAL_SEND_BACKLOG_CHANGE和SIO_IDEAL_SEND_BACKLOG_QUERY IOCTL 的典型用法基于应用程序使用的发送方法。 讨论了两种常见情况。
一次执行一个阻止或非阻止发送请求的应用程序通常依赖于 Winsock 的内部发送缓冲来实现体面的吞吐量。 给定连接的发送缓冲区限制由 SO_SNDBUF 套接字选项控制。 对于阻塞和非阻塞发送方法,发送缓冲区限制确定在 TCP 中保留的未完成数据量。 如果连接的 ISB 值大于发送缓冲区限制,则连接上实现的吞吐量将不是最佳。 为了获得更好的吞吐量,应用程序可以根据 ISB 查询的结果设置发送缓冲区限制,因为 ISB 更改通知发生在连接上。
对于使用多个未完成发送请求的重叠发送方法的应用程序,TCP 中保留的未完成数据量取决于 Winsock 中的发送缓冲区限制和未完成的重叠发送请求中包含的数据总量。 在这种情况下,应用程序应使用 ISB 值来确定它们应保留多少个未完成的发送请求,以及每个发送请求的数据大小。 理想情况下,应用程序应尝试满足以下公式:
ISB value == send buffer limit + (number of simultaneous overlapped send requests * data length per send request)
请注意,以上述方式通过 TCP 套接字使用 ISB IOCTL 可能会导致内存使用量增加,从而在具有高带宽延迟产品的连接上增加吞吐量。 Windows 中的 TCP 实现将根据需要根据整体系统内存使用情况限制 ISB 值。
仅允许在处于连接状态的流套接字上使用 SIO_IDEAL_SEND_BACKLOG_QUERY IOCTL。 否则 WSAIoctl 或 WSPIoctl 函数将失败, WSAENOTCONN。
任何 IOCTL 都可能无限期阻止,具体取决于服务提供商的实现。 如果应用程序不能容忍 在 WSAIoctl 或 WSPIoctl 函数调用中阻止,建议对特别可能阻止的 IOCTL 使用重叠 I/O。
SIO_IDEAL_SEND_BACKLOG_QUERY IOCTL 不太可能阻止,因此它通常与设置为 NULL 的 lpOverlapped 和 lpCompletionRoutine 参数同步调用。
在以下情况下 ,SIO_IDEAL_SEND_BACKLOG_QUERY IOCTL 可能会失败并出现 WSAEINTR 或 WSA_OPERATION_ABORTED :
TCP 连接在发送方向上正常断开连接。 由于调用参数设置为 SD_SEND 的关闭函数、调用 DisconnectEx 函数,或者调用将 dwFlags 参数设置为 TF_DISCONNECT 或 TF_REUSE 的 TransmitFile 或 TransmitPackets 函数,可能会发生这种情况。 TCP 连接已重置或中止。 I/O 管理器取消请求。
Ws2tcpip.h 头文件中定义了这些 IOCTL 的两个内联包装函数。 建议使用这些内联函数,而不是直接使用 SIO_IDEAL_SEND_BACKLOG_CHANGE 和 SIO_IDEAL_SEND_BACKLOG_QUERY IOCTL。
SIO_IDEAL_SEND_BACKLOG_CHANGE IOCTL 的内联包装函数是 idealsendbacklognotify 函数。
SIO_IDEAL_SEND_BACKLOG_QUERY IOCTL 的内联包装函数是 idealsendbacklogquery 函数。
Windows 7 和 Windows Server 2008 R2 上添加了 TCP 的动态发送缓冲。 默认情况下,为 TCP 启用动态发送缓冲,除非应用程序在流套接字上设置 SO_SNDBUF 套接字选项。
建议使用 netsh 查询或设置 TCP 的动态发送缓冲。
可以使用以下命令检索 TCP 动态发送缓冲的当前值:
netsh winsock show autotuning
可以使用以下命令禁用 TCP 的动态发送缓冲:
netsh winsock set autotuning off
可以使用以下命令启用 TCP 的动态发送缓冲:
netsh winsock set autotuning on
尽管不建议这样做,但可以通过将以下注册表值设置为零,从应用程序禁用动态发送缓冲:
HKEY_LOCAL_MACHINE\SYSTEM\Current Control Set\Services\AFD\Parameters\DynamicSendBufferDisable
使用 NetSh.exe 更改动态发送缓冲的值或更改注册表值时,必须重启计算机才能使更改生效。
借助 Windows 7 和 Windows Server 2008 R2 上的动态发送缓冲,仅在特殊情况下才需要使用 SIO_IDEAL_SEND_BACKLOG_CHANGE 和 SIO_IDEAL_SEND_BACKLOG_QUERY IOCTL。