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 IOCTLs。
[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、l、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。 在这种情况下,应用程序可能会将套接字更改为阻止模式,并重新发出请求或等待相应的网络事件(例如,在
对于重叠套接字,无法立即完成的操作将启动,稍后将指示完成。 DWORD 值,l 返回的参数可能将被忽略。 当操作完成后发出相应的完成方法信号时,可以检索返回的最终完成状态和字节。
任何 IOCTL 可能会无限期阻止,具体取决于服务提供商的实现。 如果应用程序不能容忍在 WSAIoctl 调用中阻止,则特别可能阻止的 I/O 会建议重叠 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 操作码,同时提供一种便捷的方式,将操作码标识符空间分区到与 dwIoControlCode 参数一样多,现在是一个 32 位实体。 dwIoControlCode 参数是为了在添加新的控制代码时允许协议和供应商独立,同时保留与 Windows 套接字 1.1 和 Unix 控制代码的向后兼容性。 dwIoControlCode 参数采用以下格式。
我 | 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 是一个 2 位数量,用于定义 IOCTL 的类型。 定义了以下值:
0 IOCTL 是标准的 Unix IOCTL 代码,与 FIONREAD 和 FIONBIO一样。
1 IOCTL 是通用 Windows 套接字 2 IOCTL 代码。 为 Windows 套接字 2 定义的新 IOCTL 代码将具有 T == 1。
2 IOCTL 仅适用于特定地址系列。
3 IOCTL 仅适用于特定供应商的提供商,与 IOC_VENDOR一样。 此类型允许公司分配一个供应商编号,该编号显示在 供应商/地址系列 参数中。 然后,供应商可以定义特定于该供应商的新 IOCTL,而无需向清算所注册 IOCTL,从而提供供应商的灵活性和隐私。
供应商/地址系列 一个 11 位数量,用于定义拥有代码(如果 T == 3)的供应商,或者包含代码应用到的地址系列(如果 T == 2)。 如果这是 Unix IOCTL 代码(T == 0),则此参数的值与 Unix 上的代码相同。 如果这是通用 Windows 套接字 2 IOCTL (T == 1),则可以将此参数用作代码参数的扩展,以提供其他代码值。
代码 包含操作的特定 IOCTL 代码的 16 位数量。
支持以下 Unix IOCTL 代码(命令)。
支持以下 Windows 套接字 2 命令。
如果重叠的操作立即完成,WSAIoctl 返回一个值为零,并且使用输出缓冲区中的字节数更新 l 参数。 如果重叠操作已成功启动并稍后完成,此函数将返回SOCKET_ERROR并指示错误代码 WSA_IO_PENDING。 在这种情况下,
使用重叠套接字调用时,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。
从此函数返回允许对此套接字调用另一个挂起的完成例程。 可以按任意顺序调用完成例程,不一定按相同顺序调用重叠操作。
兼容性
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 应用] |
目标平台 | 窗户 |
标头 | winsock2.h |
库 | Ws2_32.lib |
DLL | Ws2_32.dll |