c++ - 为什么 WSARecvMsg 函数实现为一个函数指针,这个指针是否可以重用?

标签 c++ windows sockets

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

Note The function pointer for the WSARecvMsg function must be obtained at run time by making a call to the WSAIoctl function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified.

这有什么具体原因吗? 在使用这个函数时,我打算在启动时检索函数指针,然后从那时起始终如一地使用它。这种方法有什么问题吗?关于函数的任何更改是否意味着我们需要重新获取此指针,我们如何知道是否是这种情况?

最佳答案

根据 WSARecvMsg() documentation :

Note This function is a Microsoft-specific extension to the Windows Sockets specification

根据 WSAIoctrl() documentation :

SIO_GET_EXTENSION_FUNCTION_POINTER (opcode setting: O, I, T==1)
Retrieve a pointer to the specified extension function supported by the associated service provider. The input buffer contains a globally unique identifier (GUID) whose value identifies the extension function in question. The pointer to the desired function is returned in the output buffer. Extension function identifiers are established by service provider vendors and should be included in vendor documentation that describes extension function capabilities and semantics.

在大多数系统上,Microsoft 的提供程序是唯一安装的提供程序。但是,确实存在第 3 方提供程序(自定义 TCP 堆栈等)并且也可以安装。每 WSADATA WSAStartup() 的文档:

the architecture of Windows Sockets changed in version 2 to support multiple providers, and WSADATA no longer applies to a single vendor's stack.

进一步支持:

Windows Sockets 2 Architecture

Provider-Specific Extension Mechanism

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

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

Microsoft 的提供商通过 WSAIoctrl()1 提供的其他 Microsoft 特定函数是:

  • AcceptEx()
  • ConnectEx()
  • DisconnectEx()
  • GetAcceptExSockAddrs()
  • 传输文件()
  • TransmitPackets()
  • WSASendMsg()

一旦您检索到指向供应商特定函数的指针,只要提供程序保持加载在内存中(在第一次调用 WSAStartup() 之间),您就可以尽可能多地重用该指针> 以及对 WSACleanup()) 的最后一次调用,然后将属于该提供程序的 SOCKET 传递给它。

1:根据 Provider-Specific Extension Mechanism

On Windows Vista and later, new Winsock system extensions are exported directly from the Winsock DLL, so the WSAIoctl function is not needed to load these extensions. The new extension functions available on Windows Vista and later include the WSAPoll and WSASendMsg functions that are exported from Ws2_32.dll.

关于c++ - 为什么 WSARecvMsg 函数实现为一个函数指针,这个指针是否可以重用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37355397/

相关文章:

c++ - 从已编译的应用程序创建 Windows 服务

windows - 当后续列有图像时,列表控件将图像的空间添加到列 0

java - UDP 数据包内容在传输时发生变化

c++ - 操作 wchar 时遇到问题

java - 这是什么文档格式?

c++ - 将 CComBSTR 与 NULL 进行比较

Eclipse 中的编译时错误 : "undefined reference to ` sctp_recvmsg'"

c++ - typedef 标准集合时的命名约定

python - 在 Windows 10 上安装 weasyprint 的问题

c++ - TCP 套接字 - 服务器不接受任何连接 UNIX