LPWSPDUPLICATESOCKET 回调函数 (ws2spi.h)

LPWSPDuplicateSocket 函数返回一个 WSAPROTOCOL_INFO 结构,该结构可用于为共享套接字创建新的套接字描述符。

语法

LPWSPDUPLICATESOCKET Lpwspduplicatesocket;

int Lpwspduplicatesocket(
  [in]  SOCKET s,
  [in]  DWORD dwProcessId,
  [out] LPWSAPROTOCOL_INFOW lpProtocolInfo,
  [out] LPINT lpErrno
)
{...}

参数

[in] s

本地套接字描述符。

[in] dwProcessId

将使用共享套接字的目标进程的标识符。

[out] lpProtocolInfo

指向客户端分配的缓冲区的指针,该缓冲区足够大,足以包含 WSAPROTOCOL_INFO 结构。 服务提供商将协议信息结构内容复制到此缓冲区。

[out] lpErrno

指向错误代码的指针。

返回值

如果未发生错误,LPWSPDuplicateSocket 返回零。 否则,返回SOCKET_ERROR的值,lpErrno中提供了特定的错误号。

错误代码 意义
WSAENETDOWN
网络子系统已失败。
WSAEINVAL
指示指定参数之一无效。
WSAEINPROGRESS
正在阻止 Windows 套接字调用,或者服务提供商仍在处理回调函数。
WSAEMFILE
没有更多套接字描述符可用。
WSAENOBUFS
没有可用的缓冲区空间。 无法创建套接字。
WSAENOTSOCK
描述符不是套接字。

言论

源进程调用 LPWSPDuplicateSocket 以获取特殊的 WSAPROTOCOL_INFO 结构。 它使用一些进程间通信(IPC)机制将此结构的内容传递给目标进程,后者反过来又在调用 LPWSPSocket 以获取重复套接字的描述符。 请注意,特殊 WSAPROTOCOL_INFO 结构只能由目标进程使用一次。

服务提供商负责在源进程上下文中执行所需的任何操作,并创建一个 WSAPROTOCOL_INFO 结构,该结构随后在目标进程的上下文中显示为 LPWSPSocket 的参数时将被识别。 然后,提供程序必须返回引用公共基础套接字的套接字描述符。 WSAPROTOCOL_INFO 结构的 dwProviderReserved 成员可供服务提供商使用,可用于存储任何有用的上下文信息,包括重复的句柄。

分配新的套接字描述符时,可安装文件系统(IFS)提供程序必须调用 WPUModifyIFSHandle,并且非 IFS 提供程序必须调用 WPUCreateSocketHandle。 IFS 提供程序可以使用 DuplicateHandle 函数。 为了确保正确执行套接字重复,非 IFS 服务提供商必须使用 LPWSPDuplicateSocket 函数。

下面说明了在切换模式下建立和使用共享套接字的一种可能方案。

源进程 IPC 意义
1) LPWSPSocketLPWSPConnect
2) 请求目标进程标识符。
==>
3) 接收进程标识符请求和响应。
4) 接收进程标识符。
<==
5) 调用 **LPWSPDuplicateSocket** 以获取特殊的 WSAPROTOCOL_INFO 结构。
6) 将 WSAPROTOCOL_INFO 结构发送到目标。
==> 7) 接收 WSAPROTOCOL_INFO 结构。
8) LPWSPSocket 调用以创建共享套接字描述符。
9) 使用共享套接字进行数据交换。
10) LPWSPCloseSocket
<==

就 I/O 而言,引用共享套接字的描述符可以独立使用。 但是,Windows 套接字接口不实现任何类型的访问控制,因此由所涉及的进程来协调其在共享套接字上的操作。 共享套接字的典型用途是有一个负责创建套接字和建立连接的进程,将套接字移交给负责信息交换的其他进程。

由于复制的内容是套接字描述符,而不是基础套接字,因此所有描述符中都保留与套接字关联的所有状态。 例如,使用一个描述符执行的 WSPSetSockOpt 操作随后使用来自任何或所有描述符的 LPWSPGetSockopt 可见。 进程可以在重复套接字上调用 LPWSPCloseSocket,描述符将解除分配。 但是,基础套接字将保持打开状态,直到最后一个剩余描述符调用 LPWSPClosesocket

有关共享套接字的通知受 LPWSPAsyncSelectLPWSPEventSelect的常规约束的约束。 使用任何共享描述符发出上述任一调用都会取消套接字的任何以前的事件注册,而不考虑使用哪个描述符进行该注册。 因此,例如,共享套接字无法将FD_READ事件传送到处理 A 并FD_WRITE事件来处理 B。对于需要这种紧密协调的情况,建议开发人员使用线程而不是单独的进程。

分层服务提供商提供此函数的实现,但如果调用协议链中下一层 LPWSPDuplicateSocket,则也是此函数的客户端。 一些特殊注意事项适用于此函数的 lpProtocolInfo 参数,因为它通过协议链的层传播。

如果协议链中的下一层是另一层,则当调用下一层的 LPWSPDuplicateSocket 时,此层必须传递给下一层,lpProtocolInfo,该层引用具有相同未修改链信息的相同未修改 WSAPROTOCOL_INFO 结构。 但是,如果下一层是基协议(即链中的最后一个元素),则调用基提供程序的 LPWSPDuplicateSocket时,此层将执行替换。 在这种情况下,基础提供程序 WSAPROTOCOL_INFO 结构应由 lpProtocolInfo 参数引用。

此策略的一个重要好处是基础服务提供商不必了解协议链。 当通过其他函数的分层序列(如 LPWSPAddressToStringWSPStartupLPWSPSocketLPWSPStringToAddress)传播 WSAPROTOCOL_INFO 结构时,同样适用此策略。

要求

要求 价值
最低支持的客户端 Windows 2000 Professional [仅限桌面应用]
支持的最低服务器 Windows 2000 Server [仅限桌面应用]
标头 ws2spi.h

另请参阅

WPUCreateSocketHandle

WPUModifyIFSHandle