WSAJoinLeaf 函数 (winsock2.h)

WSAJoinLeaf 函数将叶节点联接到多点会话中,交换连接数据,并根据指定的 FLOWSPEC 结构指定所需的服务质量。

语法

SOCKET WSAAPI WSAJoinLeaf(
  [in]  SOCKET         s,
  [in]  const sockaddr *name,
  [in]  int            namelen,
  [in]  LPWSABUF       lpCallerData,
  [out] LPWSABUF       lpCalleeData,
  [in]  LPQOS          lpSQOS,
  [in]  LPQOS          lpGQOS,
  [in]  DWORD          dwFlags
);

参数

[in] s

标识多点套接字的描述符。

[in] name

要联接套接字的对等方的名称。

[in] namelen

名称的长度(以字节为单位)。

[in] lpCallerData

指向在建立多点会话期间要传输到对等方的用户数据的指针。

[out] lpCalleeData

指向在建立多点会话期间要从对等方传输回的用户数据的指针。

[in] lpSQOS

指向套接字 的FLOWSPEC 结构的指针,每个方向各一个。

[in] lpGQOS

保留以供将来与套接字组一起使用。 指向套接字组 的 FLOWSPEC 结构的指针 ((如果适用) )。

[in] dwFlags

指示套接字充当发送方 (JL_SENDER_ONLY) 、接收方 (JL_RECEIVER_ONLY) 或同时充当 (JL_BOTH) 的标志。

返回值

如果未发生错误, WSAJoinLeaf 将返回 SOCKET 类型的值,该值是新创建的多点套接字的描述符。 否则,将返回值 INVALID_SOCKET,并且可以通过调用 WSAGetLastError 来检索特定的错误代码。

在阻塞套接字上,返回值指示联接操作成功或失败。

使用非阻止套接字时,通过返回有效的套接字描述符指示成功启动联接操作。 随后,当联接操作成功或以其他方式 完成时, 将在原始套接字 上发出FD_CONNECT指示。 应用程序必须使用 WSAAsyncSelectWSAEventSelect ,该事件已注册FD_CONNECT事件,以便确定联接操作何时完成,并检查关联的错误代码以确定操作是成功还是失败。 select 函数不能用于确定联接操作何时完成。

此外,在多点会话联接尝试完成对同一套接字上的 WSAJoinLeaf 的所有后续调用之前,将失败并显示错误代码 WSAEALREADYWSAJoinLeaf 操作成功完成后,后续尝试通常会失败并显示错误代码 WSAEISCONN。 对于允许根发起的联接的c_root套接字,WSAEISCONN 规则将发生异常。 在这种情况下,可以在之前的 WSAJoinLeaf 操作完成后启动另一个联接。

如果返回错误代码指示多点会话联接尝试失败 (即 WSAECONNREFUSEDWSAENETUNREACHWSAETIMEDOUT) 则应用程序可以为同一套接字再次调用 WSAJoinLeaf

错误代码 含义
WSANOTINITIALISED
在使用此函数之前,必须成功调用 WSAStartup
WSAEADDRINUSE
套接字的本地地址已在使用中,并且未将套接字标记为允许使用 SO_REUSEADDR 重用地址。 此错误通常在 绑定时发生,但如果 绑定到 涉及ADDR_ANY) 的部分通配符地址 (,并且需要在此函数时提交特定地址,则可能会延迟到此函数。
WSAEADDRNOTAVAIL
远程地址不是有效的地址 (,例如 ADDR_ANY) 。
WSAEAFNOSUPPORT
指定系列中的地址无法与此套接字一起使用。
WSAEALREADY
在指定的套接字上正在进行非阻止 WSAJoinLeaf 调用。
WSAECONNREFUSED
试图加入被强行拒绝。
WSAEFAULT
namenamelen 参数不是用户地址空间的有效部分,namelen 参数太小,lpCalleeDatalpSQOSlpGQOS 的缓冲区长度太小,或者 lpCallerData 的缓冲区长度太大。
WSAEINVAL
WSAJoinLeaf 函数调用是在未设置其WSA_FLAG_MULTIPOINT_C_LEAF或WSA_FLAG_MULTIPOINT_D_LEAF多点标志的情况下打开的 UDP 套接字上执行的。
WSAEISCONN
套接字已是多点会话的成员。
WSAEINTR
阻止的 Windows 套接字 1.1 调用已通过 WSACancelBlockingCall 取消。
WSAEINPROGRESS
阻止 Windows Sockets 1.1 调用正在进行,或者服务提供程序仍在处理回调函数。
WSAENETDOWN
网络子系统失败。
WSAENETUNREACH
此时不可以从此主机访问该网络。
WSAENOBUFS
未提供任何缓冲区空间。 无法联接套接字。
WSAENOTSOCK
:描述符不是套接字。
WSAEOPNOTSUPP
不能满足 lpSQOSlpGQOS 中指定的 FLOWSPEC 结构。
WSAEPROTONOSUPPORT
服务提供商不支持 lpCallerData 扩充。
WSAETIMEDOUT
未建立多点会话的加入尝试超时。

注解

WSAJoinLeaf 函数用于将叶节点联接到多点会话,并执行在会话加入时发生的许多其他辅助操作。 如果 套接字未 绑定,则系统会将唯一值分配给本地关联,并将套接字标记为绑定。

WSAJoinLeaf 函数的参数和语义与 WSAConnect 相同,只不过它返回 (WSAAccept) 中的套接字描述符,并且具有额外的 dwFlags 参数。 在此函数中,只有使用 WSASocket 创建并设置了适当多点标志的多点套接字才能用于输入参数 。 返回的套接字描述符在联接操作完成后才可用。 例如,如果在从原始套接字上的 WSAAsyncSelectWSAEventSelect 收到相应的FD_CONNECT指示 后,套接字处于非阻止模式,不同之处在于,可以在此新套接字描述符上调用 closesocket 来取消挂起的联接操作。 多点会话中的根应用程序可能会调用 WSAJoinLeaf 一次或多次,以便添加多个叶节点,但一次最多只能有一个多点连接请求未完成。 有关其他信息,请参阅 多点和多播语义

对于非阻塞套接字,通常无法立即完成连接。 在这种情况下,此函数返回一个尚不可用的套接字描述符,并且操作继续进行。 在这种情况下,没有类似于 WSAEWOULDBLOCK 的错误代码,因为函数已有效地返回成功的启动指示。 当最终结果成功或失败时,可能会通过 WSAAsyncSelectWSAEventSelect 进行报告,具体取决于客户端在 原始套接字上注册通知的方式。 在任一情况下,通知都以FD_CONNECT播报,并且与FD_CONNECT关联的错误代码指示成功或失败的特定原因。 select 函数不能用于检测 WSAJoinLeaf 的完成通知。

WSAJoinLeaf 返回的套接字描述符会有所不同,具体取决于输入套接字描述符 s 是c_root还是c_leaf。 与 c_root 套接字一起使用时, name 参数指定要添加的特定叶节点,并且返回的套接字描述符是对应于新添加的叶节点的c_leaf套接字。 新创建的套接字具有与 相同的属性,包括向 WSAAsyncSelectWSAEventSelect 注册的异步事件。 它不用于交换多点数据,而是用于接收网络事件指示 (例如,FD_CLOSE) 与特定c_leaf的连接。 某些多点实现还允许将此套接字用于根节点和单个叶节点之间的旁聊天。 如果相应的叶节点调用 closesocket 退出多点会话,则会收到此套接字的FD_CLOSE指示。 对称地,在从 WSAJoinLeaf 返回的c_leaf套接字上调用 closesocket 将导致相应叶节点中的套接字收到FD_CLOSE通知。

使用c_leaf套接字调用 WSAJoinLeaf 时, name 参数包含根控制方案 (的地址) 或现有多点会话 (非根控制方案) ,返回的套接字描述符与输入套接字描述符相同。 换句话说,不会分配新的套接字描述符。 在根控制方案中,根应用程序会通过调用 listen 将其c_root套接字置于侦 模式。 当叶节点请求将自身加入多点会话时,将传递标准FD_ACCEPT通知。 根应用程序使用常用的 acceptWSAAccept 函数来允许新的叶节点。 从 acceptWSAAccept 返回的值也是c_leaf套接字描述符,就像从 WSAJoinLeaf 返回的值一样。 为了适应同时允许根发起联接和叶发起联接的多点方案,可以接受已处于侦听模式的c_root套接字用作 WSAJoinLeaf 的输入。

应用程序负责分配它指定的任何参数直接或间接指向的任何内存空间。

lpCallerData 是一个值参数,其中包含要随多点会话加入请求一起发送的任何用户数据。 如果 lpCallerDataNULL,则不会将用户数据传递给对等方。 lpCalleeData 是一个结果参数,它将包含作为多点会话建立的一部分从对等方传回的任何用户数据。 lpCalleeData 参数指向的 WSABUF 结构的 len 成员最初包含由应用程序分配并由 WSABUF 结构的 buf 成员指向的缓冲区的长度。 如果未传回任何用户数据,则 lpCalleeData 参数指向的 WSABUF 结构的 len 成员将被设置为零。 多点联接操作完成后, lpCalleeData 信息将有效。

对于阻塞套接字,这将在 WSAJoinLeaf 函数返回时出现。 对于非阻止套接字,这将在联接操作完成后进行。 例如,在 原始套接字) 上FD_CONNECT通知后,可能会发生这种情况。 如果 lpCalleeDataNULL,则不会传回任何用户数据。 用户数据的确切格式特定于套接字所属的地址系列。

在多点会话建立时,应用程序可以使用 lpSQOS 和/或 lpGQOS 参数替代以前通过 WSAIoctl 使用SIO_SET_QOS或SIO_SET_GROUP_QOS操作码为套接字制定的任何服务质量规范。

lpSQOS 参数指定套接字FLOWSPEC 结构,每个方向各一个,后跟任何其他特定于提供程序的参数。 如果一般情况下关联的传输提供程序或特定类型的套接字无法遵循服务质量请求,则将返回错误,如下所述。 对于任何单向套接字,将忽略相应的发送或接收流规范值。 如果未指定提供程序特定的参数,则 lpCalleeData 参数指向的 WSABUF 结构的 buflen 成员应分别设置为 NULL 和零。 lpSQOSNULL 值表示没有应用程序提供的服务质量。

保留给将来的套接字组。 lpGQOS 参数指定套接字组的 FLOWSPEC 结构(如果适用) () ,每个方向各一个,后跟任何其他特定于提供程序的参数。 如果未指定特定于提供程序的参数,则 lpCalleeData 参数指向的 WSABUF 结构的 buflen 成员应分别设置为 NULL 和零。 lpGQOSNULL 值表示没有应用程序提供的组服务质量。 如果 不是套接字组的创建者,则将忽略此参数。

当连接的套接字中断 (也就是说,由于任何原因) 关闭时,应将其丢弃并重新创建。 最安全的假设是,当由于任何原因在连接的套接字上出现问题时,应用程序必须放弃并重新创建所需的套接字才能返回到稳定点。

注意 发出阻止的 Winsock 调用(如 WSAJoinLeaf)时,Winsock 可能需要等待网络事件,然后才能完成调用。 在这种情况下,Winsock 执行可发出警报的等待, (在同一线程上计划的 APC) 异步过程调用可能会中断。 在 APC 内发出另一个阻止 Winsock 调用,该调用中断了同一线程上正在进行的阻止 Winsock 调用将导致未定义的行为,并且 Winsock 客户端绝不能尝试。
 
Windows Phone 8:Windows Phone 8 及更高版本上的 Windows Phone 应用商店应用支持此函数。

Windows 8.1Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更高版本的 Windows 应用商店应用支持此函数。

要求

要求
最低受支持的客户端 Windows 8.1,Windows Vista [桌面应用 |UWP 应用]
最低受支持的服务器 Windows Server 2003 [桌面应用 | UWP 应用]
目标平台 Windows
标头 winsock2.h
Library Ws2_32.lib
DLL Ws2_32.dll

另请参阅

WSAAccept

WSAAsyncSelect

WSABUF

WSAEventSelect

WSASocket

Winsock 函数

Winsock 参考

accept

bind

select