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,该 lpProtocolInfo 引用具有相同未修改的链信息的相同未修改 WSAPROTOCOL_INFO 结构。 但是,如果下一层是基本协议 (即链) 中的最后一个元素,则此层在调用基提供程序的 LPWSPDuplicateSocket 时执行替换。 在这种情况下,lpProtocolInfo 参数应引用基提供程序的WSAPROTOCOL_INFO结构。

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

要求

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

另请参阅

WPUCreateSocketHandle

WPUModifyIFSHandle