为什么WSARecvMsg函数实现为函数指针并且可以重用此指针?

时间:2016-05-20 20:32:22

标签: c++ windows sockets

here 所述的WSARecvMsg函数要求您检索一个指向它的函数指针,如下面的引用所示:

  

注意必须在运行时通过使用指定的SIO_GET_EXTENSION_FUNCTION_POINTER操作码调用WSAIoctl函数来获取WSARecvMsg函数的函数指针。

这是否有特定原因? 在使用这个函数时,我打算在启动时检索函数指针,然后从那时开始一直使用它。这种方法有什么问题吗?关于函数的任何改变都意味着我们需要重新获取这个指针,我们怎么知道是不是这样呢?

1 个答案:

答案 0 :(得分:13)

根据WSARecvMsg() documentation

  

注意此功能是Windows套接字规范的特定于Microsoft的扩展

根据WSAIoctrl() documentation

  

SIO_GET_EXTENSION_FUNCTION_POINTER(操作码设置:O,I,T == 1)
  检索指向相关服务提供商支持的指定扩展功能的指针。输入缓冲区包含全局唯一标识符(GUID),其值标识所讨论的扩展函数。指向所需函数的指针在输出缓冲区中返回。扩展功能标识符由服务提供商供应商建立,应包含在描述扩展功能和语义的供应商文档中。

在大多数系统上,Microsoft的提供商是唯一安装的提供商。但是,第三方提供商确实存在(自定义TCP堆栈等),也可以安装。每个 WSAStartup()的{​​{3}}文档:

  

Windows Sockets的体系结构在版本2中更改为支持多个提供程序,并且WSADATA不再适用于单个供应商的堆栈。

进一步支持:

WSADATA

Windows Sockets 2 Architecture

使用socket()创建套接字时,您无法控制使用哪个提供程序。当您使用WSASocket()创建套接字时,您可以选择通过lpProtocolInfo参数指定特定提供商。

WSARecvMsg()仅在Microsoft的提供程序中可用,因此您必须将其传递给与同一提供程序关联的SOCKETWSAIoctrl()可用于向SOCKET所属的提供程序发送命令。因此,通过使用SIO_GET_EXTENSION_FUNCTION_POINTER,您可以确保指定WSARecvMsg()的提供程序支持SOCKET(或任何其他特定于供应商的函数),从而与SOCKET兼容}。

Microsoft提供商通过WSAIoctrl() 1 提供的其他Microsoft特定功能包括:

  • AcceptEx()
  • ConnectEx()
  • DisconnectEx()
  • GetAcceptExSockAddrs()
  • TransmitFile()
  • TransmitPackets()
  • WSASendMsg()

一旦检索到特定于供应商的函数的指针,只要提供程序在内存中加载(在第一次调用WSAStartup()和最后一次调用之间),就可以根据需要重复使用指针。到WSACleanup())并传递属于该提供商的SOCKET

1 :每Provider-Specific Extension Mechanism

  

在Windows Vista及更高版本中,新的Winsock系统扩展直接从Winsock DLL导出,因此不需要WSAIoctl函数来加载这些扩展。 Windows Vista及更高版本中提供的新扩展功能包括从Ws2_32.dll导出的WSAPollWSASendMsg函数。