WSAIoctl 函数 (winsock2.h)
WSAIoctl 函数控制套接字的模式。
语法
int WSAAPI WSAIoctl(
[in] SOCKET s,
[in] DWORD dwIoControlCode,
[in] LPVOID lpvInBuffer,
[in] DWORD cbInBuffer,
[out] LPVOID lpvOutBuffer,
[in] DWORD cbOutBuffer,
[out] LPDWORD lpcbBytesReturned,
[in] LPWSAOVERLAPPED lpOverlapped,
[in] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
参数
[in] s
标识套接字的描述符。
[in] dwIoControlCode
要执行的操作的控制代码。 请参阅 Winsock IOCTL。
[in] lpvInBuffer
指向输入缓冲区的指针。
[in] cbInBuffer
输入缓冲区的大小(以字节为单位)。
[out] lpvOutBuffer
指向输出缓冲区的指针。
[in] cbOutBuffer
输出缓冲区的大小(以字节为单位)。
[out] lpcbBytesReturned
指向输出的实际字节数的指针。
[in] lpOverlapped
对于非重叠套接字) , (忽略指向 WSAOVERLAPPED 结构的指针。
[in] lpCompletionRoutine
类型:_In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE
返回值
成功完成后, WSAIoctl 返回零。 否则,将返回值 SOCKET_ERROR,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。
错误代码 | 含义 |
---|---|
已成功启动重叠操作,稍后将指示完成。 | |
网络子系统失败。 | |
lpvInBuffer、lpvOutBuffer、lcbBytesReturned、lpOverlapped 或 lpCompletionRoutine 参数未完全包含在用户地址空间的有效部分,或者 cbInBuffer 或 cbOutBuffer 参数太小。 | |
dwIoControlCode 参数不是有效的命令,或者指定的输入参数不可接受,或者该命令不适用于指定的套接字类型。 | |
当回调正在进行时,将调用 函数。 | |
描述符 不是 套接字。 | |
无法实现指定的 IOCTL 命令。 (例如,无法满足 SIO_SET_QOS 或 SIO_SET_GROUP_QOS 中指定的 FLOWSPEC 结构。) | |
套接字标记为非阻塞,请求的操作将阻止。 | |
指定协议不支持套接字选项。 例如,尝试在 IPv6 套接字上使用 SIO_GET_BROADCAST_ADDRESS IOCTL,或者在数据报套接字上尝试使用 TCP SIO_KEEPALIVE_VALS IOCTL。 |
注解
WSAIoctl 函数用于设置或检索与套接字、传输协议或通信子系统关联的操作参数。
如果 lpOverlapped 和 lpCompletionRoutine 均为 NULL,则此函数中的套接字将被视为非重叠套接字。 对于非重叠套接字, 将忽略 lpOverlapped 和 lpCompletionRoutine 参数,这会导致函数的行为类似于标准 ioctlsocket 函数,只不过 当套接字 处于 阻塞模式时,函数可以阻止。 如果 套接字 处于 非阻止模式,则当无法立即完成指定的操作时,此函数可以返回 WSAEWOULDBLOCK。 在这种情况下,应用程序可能会将套接字更改为阻止模式,并重新发出请求或等待相应的网络事件 ((如FD_ROUTING_INTERFACE_CHANGE或FD_ADDRESS_LIST_CHANGE)的情况下,SIO_ROUTING_INTERFACE_CHANGE或SIO_ADDRESS_LIST_CHANGE) 使用 WSAAsyncSelect 基于) 或事件 (使用 WSAEventSelect) 通知机制的 Windows 消息 (。
对于重叠的套接字,将启动无法立即完成的操作,并在以后指示完成。 可以忽略返回的lBytesReturned 参数指向的 DWORD 值。 当操作完成时发出相应的完成方法信号时,可以检索返回的最终完成状态和字节数。
任何 IOCTL 都可能无限期阻止,具体取决于服务提供商的实现。 如果应用程序不能容忍 WSAIoctl 调用中的阻塞,则对于特别可能阻止的 IOCTL,建议使用重叠 I/O,其中包括:
SIO_ADDRESS_LIST_CHANGE
SIO_FINDROUTE
SIO_FLUSH
SIO_GET_QOS
SIO_GET_GROUP_QOS
SIO_ROUTING_INTERFACE_CHANGE
SIO_SET_QOS
SIO_SET_GROUP_QOS
某些特定于协议的 IOCTL 也可能特别可能阻止。 有关任何可用信息,请查看特定于协议的相关附件。
lpCompletionRoutine 参数指向的完成例程的原型如下所示:
#ifndef UNICODE
#define UNICODE
#endif
#define WIN32_LEAN_AND_MEAN
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>
// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")
void CALLBACK CompletionRoutine (
IN DWORD dwError,
IN DWORD cbTransferred,
IN LPWSAOVERLAPPED lpOverlapped,
IN DWORD dwFlags
);
CompletionRoutine 是应用程序提供的函数名称的占位符。 dwError 参数指定重叠操作的完成状态,如 lpOverlapped 参数所示。 cbTransferred 参数指定接收的字节数。 dwFlags 参数不用于此 IOCTL。 完成例程不返回值。
可以采用一种编码方案来保留当前定义的 ioctlsocket 操作码,同时提供一种方便的方法,将操作码标识符空间分区到 32 位实体中,就像 dwIoControlCode 参数现在是一个 32 位实体一样。 dwIoControlCode 参数的构建是为了在添加新控制代码时允许协议和供应商独立性,同时保持与 Windows 套接字 1.1 和 Unix 控制代码的向后兼容性。 dwIoControlCode 参数具有以下形式。
I | O | V | T | 供应商/地址系列 | 代码 |
---|---|---|---|---|---|
3 | 3 | 2 | 2 2 | 2 2 2 2 2 2 2 1 1 1 1 | 1 1 1 1 1 1 |
1 | 0 | 9 | 8 7 | 6 5 4 3 2 1 0 9 8 7 6 | 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 |
如果输出缓冲区对代码有效,则设置 O,就像 IOC_OUT一样。 使用输入和输出缓冲区设置 I 和 O 的控制代码。
如果代码没有参数,则设置 V,就像 IOC_VOID一样。
T 是定义 IOCTL 类型的 2 位数量。 定义了以下值:
0 IOCTL 是标准的 Unix IOCTL 代码,与 FIONREAD 和 FIONBIO 一样。
1 IOCTL 是通用 Windows 套接字 2 IOCTL 代码。 为 Windows 套接字 2 定义的新 IOCTL 代码的 T == 1。
2 IOCTL 仅适用于特定地址系列。
3 IOCTL 仅适用于特定供应商的提供商,与 IOC_VENDOR 一样。 此类型允许向公司分配显示在 Vendor/Address 系列 参数中的供应商编号。 然后,供应商可以定义特定于该供应商的新 IOCTL,而无需向清算所注册 IOCTL,从而提供供应商的灵活性和隐私性。
供应商/地址系列 一个 11 位数量,定义拥有代码 ((如果 T == 3) )或包含代码 ((如果 T == 2) )的地址系列的供应商。 如果这是 (T == 0) 的 Unix IOCTL 代码,则此参数与 Unix 上的代码具有相同的值。 如果这是通用 Windows 套接字 2 IOCTL (T == 1) 则此参数可用作代码参数的扩展来提供其他代码值。
代码 包含操作的特定 IOCTL 代码的 16 位数量。
支持以下 Unix IOCTL 代码 (命令) 。
支持以下 Windows 套接字 2 命令。
如果重叠操作立即完成, WSAIoctl 将返回一个零值,并使用输出缓冲区中的字节数更新 lhttpBytesReturned 参数。 如果已成功启动重叠操作并将稍后完成,此函数将返回SOCKET_ERROR并指示 错误代码WSA_IO_PENDING。 在本例中, 不会更新lBytesReturned 。 当重叠操作完成时,输出缓冲区中的数据量将通过完成例程 (中的 cbTransferred 参数(如果指定) )或通过 WSAGetOverlappedResult 中的 lcbTransfer 参数指示。
使用重叠套接字调用时, lpOverlapped 参数必须在重叠操作期间有效。 lpOverlapped 参数包含 WSAOVERLAPPED 结构的地址。
如果 lpCompletionRoutine 参数为 NULL,则当重叠操作完成时,如果它包含有效的事件对象句柄,则会向 lpOverlapped 的 hEvent 参数发出信号。 应用程序可以使用 WSAWaitForMultipleEvents 或 WSAGetOverlappedResult 等待或轮询事件对象。
完成例程的原型如下所示:
void CALLBACK CompletionRoutine(
IN DWORD dwError,
IN DWORD cbTransferred,
IN LPWSAOVERLAPPED lpOverlapped,
IN DWORD dwFlags
);
此 CompletionRoutine 是应用程序定义的函数或库定义的函数的占位符。 仅当线程处于可警报状态时,才会调用完成例程。 若要将线程置于可警报状态,请使用 WSAWaitForMultipleEvents、 WaitForSingleObjectEx 或 WaitForMultipleObjectsEx 函数,并将 fAlertable 或 bAlertable 参数设置为 TRUE。
CompletionRoutine 的 dwError 参数指定重叠操作的完成状态,如 lpOverlapped 所示。 cbTransferred 参数指定返回的字节数。 目前,未定义标志值, dwFlags 将为零。 CompletionRoutine 函数不返回值。
从此函数返回允许为此套接字调用另一个挂起的完成例程。 可以按任何顺序调用完成例程,不一定按照重叠操作完成的顺序调用。
兼容性
T == 0 的 IOCTL 代码是伯克利套接字中使用的 IOCTL 代码的子集。 具体而言,没有等效于 FIOASYNC 的命令。Windows 8.1和Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更高版本的 Windows 应用商店应用支持此函数。
要求
要求 | 值 |
---|---|
最低受支持的客户端 | Windows 8.1、Windows Vista [桌面应用 |UWP 应用] |
最低受支持的服务器 | Windows Server 2003 [桌面应用 | UWP 应用] |
目标平台 | Windows |
标头 | winsock2.h |
Library | Ws2_32.lib |
DLL | Ws2_32.dll |
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈