这里描述的WSARecvMsg
函数要求您检索一个函数指针,如下面的引用所示:
注意必须在运行时通过使用指定的SIO_GET_EXTENSION_FUNCTION_POINTER操作码调用WSAIoctl函数来获取WSARecvMsg函数的函数指针。
这是否有特定的原因? 在使用这个函数的时候,我打算在启动的时候检索函数指针,然后一直使用它。 这种方法有什么问题吗? 关于函数的任何改变都意味着我们需要重新获取这个指针,我们怎么知道这是否是这种情况呢?
根据WSARecvMsg()
文档 :
注意此函数是Windows套接字规范的Microsoft特定扩展
根据WSAIoctrl()
文档 :
SIO_GET_EXTENSION_FUNCTION_POINTER(操作码设置:O,I,T == 1)
检索指向相关服务提供者支持的指定扩展功能的指针 。 输入缓冲区包含一个全局唯一标识符(GUID),其值标识所讨论的扩展函数。 指向所需函数的指针在输出缓冲区中返回。 扩展功能标识符由服务提供商供应商建立,应包含在描述扩展功能和语义的供应商文档中。
在大多数系统上,微软的提供者是唯一安装的提供者。 但是,第三方提供商确实存在(自定义TCP堆栈等),也可能被安装。 根据WSAStartup()
的WSADATA
文档:
Windows套接字的体系结构在版本2中更改为支持多个提供程序 ,而WSADATA不再适用于单个供应商的堆栈。
其中进一步支持:
Windows套接字2架构
特定于提供者的扩展机制
当你使用socket()
创建一个套接字时,你不能控制使用哪个提供者。 当您使用WSASocket()
创建套接字时,您可以通过lpProtocolInfo
参数指定特定的提供者。
WSARecvMsg()
仅在Microsoft的提供程序中可用,因此您必须将它传递WSARecvMsg()
同一提供程序关联的SOCKET
。 WSAIoctrl()
可用于将命令发送到SOCKET
所属的提供程序。 因此,通过使用SIO_GET_EXTENSION_FUNCTION_POINTER
,您可以确保WSARecvMsg()
(或任何其他供应商特定的函数)由指定SOCKET
的提供者支持,因此与该SOCKET
兼容。
微软的供应商通过WSAIoctrl()
1提供的其他微软特定功能是:
AcceptEx()
ConnectEx()
DisconnectEx()
GetAcceptExSockAddrs()
TransmitFile()
TransmitPackets()
WSASendMsg()
一旦检索到指向特定于供应商的函数的指针,只要提供程序保持加载到内存中(在第一次调用WSAStartup()
和最后一次调用WSACleanup()
),就可以随意使用指针了。并且将它传递给属于该提供者的SOCKET
。
1 :每个提供商特定的扩展机制
在Windows Vista和更高版本中, 新的Winsock系统扩展从Winsock DLL直接导出,所以WSAIoctl函数不需要加载这些扩展 。 Windows Vista和更高版本中提供的新扩展功能包括从Ws2_32.dll导出的
WSAPoll
和WSASendMsg
函数。