LPWSPEVENTSELECT 回调函数 (ws2spi.h)

LPWSPEventSelect 函数指定要与提供的一组网络事件关联的事件对象。

语法

LPWSPEVENTSELECT Lpwspeventselect;

int Lpwspeventselect(
  [in]  SOCKET s,
  [in]  WSAEVENT hEventObject,
  [in]  long lNetworkEvents,
  [out] LPINT lpErrno
)
{...}

参数

[in] s

标识套接字的描述符。

[in] hEventObject

标识要与提供的一组网络事件关联的事件对象的句柄。

[in] lNetworkEvents

指定 Windows Sockets SPI 客户端感兴趣的网络事件的组合的位掩码。 使用带上述任何值的按位 OR 运算符构造。

价值 意义
FD_READ
有关阅读准备情况的通知。
FD_WRITE
写入准备情况通知的问题。
FD_OOB
发出 OOB 数据的到达通知。
FD_ACCEPT
发出传入连接的通知。
FD_CONNECT
已完成连接的问题通知。
FD_CLOSE
发出套接字关闭通知。
FD_QOS
套接字(QoS)更改通知的问题。
FD_GROUP_QOS
保留。
FD_ROUTING_INTERFACE_CHANGE
发出指定目标的路由接口更改通知。
FD_ADDRESS_LIST_CHANGE
对套接字的地址系列更改的本地地址列表更改发出通知。

[out] lpErrno

指向错误代码的指针。 有关详细信息,请参阅 返回值 部分。

返回值

如果 Windows Sockets SPI 客户端的网络事件规范和关联的事件对象成功,则返回值为零。 否则,返回值 SOCKET_ERRORlpErrno中提供了特定的错误号。

错误代码 意义
WSAENETDOWN
网络子系统已失败。
WSAEINVAL
指示指定参数之一无效,或者指定的套接字处于无效状态。
WSAEINPROGRESS
正在阻止 Windows 套接字调用,或者服务提供商仍在处理回调函数。
WSAENOTSOCK
描述符不是套接字。

言论

此函数用于指定与所选网络事件关联的事件对象,hEventObjectlNetworkEvents。 指定事件对象的套接字由 s标识。 当发生任何指定的网络事件时,将设置事件对象。

LPWSPEventSelect 操作与 LPWSPAsyncSelect非常类似,不同之处在于在发生指定网络事件时执行的操作。 而 WSPAsyncSelect 会导致发布 Windows 套接字 SPI 客户端指定的 Windows 消息,LPWSPEventSelect 设置关联的事件对象,并在内部网络事件记录中记录此事件的发生。 Windows Sockets SPI 客户端可以使用 LPWSPEnumNetworkEvents 检索内部网络事件记录的内容,从而确定已发生的指定网络事件。

LPWSPEventSelect 是唯一导致通过 LPWSPEnumNetworkEvents记录和检索网络活动和错误的函数。 请参阅 LPWSPSelectLPWSPAsyncSelect 的说明,了解这些函数如何报告网络活动和错误。

无论 lNetworkEvents的值如何,此函数都会自动将套接字 设置为非阻止模式。

为套接字发出 LPWSPEventSelect 会取消任何以前的 LPWSPAsyncSelectLPWSPEventSelect,并清除内部网络事件记录。 例如,若要将事件对象与读取和写入网络事件相关联,Windows Sockets SPI 客户端必须调用 LPWSPEventSelect,FD_READ和FD_WRITE,如下所示。

rc = WSPEventSelect(s, hEventObject, FD_READ | FD_WRITE);

无法为不同的网络事件指定不同的事件对象。 以下代码不起作用;第二次调用将取消第一次的效果,唯一的关联将是与 hEventObject2 关联的FD_WRITE网络事件。

// Incorrect example.
rc = WSPEventSelect(s, hEventObject1, FD_READ);
rc = WSPEventSelect(s, hEventObject2, FD_WRITE);

若要取消套接字上的网络事件的关联和选择,应将 lNetworkEvents 设置为零,在这种情况下,将忽略 hEventObject 参数。

rc = WSPEventSelect(s, hEventObject, 0);

关闭 LPWSPCloseSocket 的套接字也会取消套接字在 LPWSPEventSelect 中指定的网络事件的关联和选择。 但是,Windows 套接字 SPI 客户端仍必须调用 WSACloseEvent 显式关闭事件对象,并释放任何资源。

由于 LPWSPAccept“ed 套接字”的属性与用于接受它的侦听套接字具有相同的属性,因此任何 LPWSPEventSelect 关联和侦听套接字的网络事件选择集都适用于接受的套接字。 例如,如果侦听套接字 LPWSPEventSelecthEventObject 与FD_ACCEPT、FD_READ和FD_WRITE,则该侦听套接字上接受的任何套接字也将具有FD_ACCEPT、FD_READ以及与同一 hEventObject关联的FD_WRITE网络事件。 如果需要其他 hEventObject 或网络事件,则 Windows 套接字 SPI 客户端应调用 LPWSPEventSelect、传递接受的套接字以及所需的新信息。

成功记录网络事件的发生并发出关联事件对象的信号后,在 Windows Sockets SPI 客户端发出函数调用之前,不会对该网络事件执行进一步操作,从而隐式重新启用该网络事件的设置和关联事件对象的信号。

网络事件 重新启用函数
FD_READ LPWSPRecvLPWSPRecvFrom
FD_WRITE LPWSPSendLPWSPSendTo
FD_OOB LPWSPRecvLPWSPRecvFrom
FD_ACCEPT LPWSPAccept,除非返回的错误代码WSATRY_AGAIN指示条件函数返回CF_DEFER
FD_CONNECT 没有
FD_CLOSE 没有
FD_QOS 使用 SIO_GET_QOS LPWSPIoctl
FD_GROUP_QOS 保留用于套接字组的未来用途:LPWSPIoctl 与 SIO_GET_GROUP_QOS
FD_ROUTING_INTERFACE_CHANGE 使用命令SIO_ROUTING_INTERFACE_CHANGE LPWSPIoctl
FD_ADDRESS_LIST_CHANGE 使用命令SIO_ADDRESS_LIST_CHANGE LPWSPIoctl

对重新启用例程的任何调用(即使是失败的例程)都会导致重新启用相关网络事件和事件对象的录制和信号。

对于FD_READ、FD_OOB和FD_ACCEPT网络事件,网络事件记录和事件对象信号 级别触发。 这意味着,如果调用重新启用例程,并且相关网络条件在调用后仍然有效,则记录网络事件并发出关联的事件对象信号。 这样,Windows Sockets SPI 客户端就可以由事件驱动,同时对任何一次到达的数据量不满意。 请考虑以下顺序。

  1. 服务提供商在套接字 上接收 100 字节的数据,记录FD_READ网络事件,并向关联的事件对象发出信号。
  2. Windows 套接字 SPI 客户端 WSPRecv(s, buffptr, 50, 0) 读取 50 字节时出现问题。
  3. 服务提供商记录FD_READ网络事件,并再次向关联的事件对象发出信号,因为仍有要读取的数据。

借助这些语义,Windows Sockets SPI 客户端无需读取所有可用数据即可响应FD_READ网络事件。 相反,响应每个FD_READ网络事件的单个 LPWSPRecv 是适当的。

FD_QOS和FD_GROUP_QOS事件被视为 边缘触发。 当发生服务质量(QOS)更改时,将恰好发布一次消息。 在服务提供商检测到 QOS 中的进一步更改或 Windows 套接字 SPI 客户端重新协商套接字的 QOS 之前,不会发出进一步指示。

FD_ROUTING_INTERFACE_CHANGE和FD_ADDRESS_LIST_CHANGE事件也被视为 边缘触发。 在 Windows 套接字 SPI 客户端发出 WSAIoctl 并相应地发出SIO_ROUTING_INTERFACE_CHANGE或SIO_ADDRESS_LIST_CHANGE 后,发生更改后,将恰好发布一条消息。 在 Windows 套接字 SPI 客户端重新发出 IOCTL 并检测到另一个更改后,才会发出进一步消息, 检测到另一个更改。

如果 Windows 套接字 SPI 客户端调用 LPWSPEventSelect或调用重新启用函数时已发生网络事件,则会记录网络事件,并相应地发出关联的事件对象的信号。 例如,请考虑以下序列。

  1. Windows 套接字 SPI 客户端调用 LPWSPListen
  2. 收到连接请求,但尚未接受。
  3. Windows Sockets SPI 客户端 LPWSPEventSelect 指定对套接字FD_ACCEPT网络事件感兴趣。 服务提供商记录FD_ACCEPT网络事件,并立即向关联的事件对象发出信号。

FD_WRITE网络事件处理方式略有不同。 当套接字首次连接到 LPWSPConnect 或接受 LPWSPAccept时,将记录FD_WRITE网络事件,然后在 LPWSPSendLPWSPSendTo 失败且 WSAEWOULDBLOCK 和缓冲区空间可用后。 因此,Windows 套接字 SPI 客户端可以假定从第一个FD_WRITE网络事件设置开始发送,并且持续到发送返回 WSAEWOULDBLOCK。 发生此类故障后,Windows Sockets SPI 客户端将发现,当记录FD_WRITE网络事件并发出关联的事件对象信号时,发送将再次可能发送。

仅当套接字配置为单独接收带外数据时,才会使用FD_OOB网络事件。 如果套接字配置为内联接收带外数据,则将带外(加速)数据视为正常数据,并且 Windows Sockets SPI 客户端应注册感兴趣的内容,并获取FD_READ网络事件,而不是FD_OOB网络事件。 Windows 套接字 SPI 客户端可以使用 LPWSPSetSockOptLPWSPGetSockOpt 为SO_OOBINLINE选项设置或检查带外数据处理的方式。

FD_CLOSE网络事件中的错误代码指示套接字关闭是正常还是中止。 如果错误代码为 0,则关闭操作正常;如果错误代码为 WSAECONNRESET,则重置套接字的虚拟线路。 这仅适用于面向连接的套接字,例如SOCK_STREAM。

当收到对应于套接字的虚拟线路的关闭指示时,将记录FD_CLOSE网络事件。 在 TCP 术语中,这意味着当连接进入 FIN WAIT 或 CLOSE WAIT 状态时,将记录FD_CLOSE。 这会导致远程端在发送端执行 LPWSPShutdown,或 LPWSPCloseSocket

服务提供商应仅记录 FD_CLOSE网络事件,以指示虚拟线路关闭;它应 记录FD_READ网络事件以指示该条件。

当流规范中与套接字 关联的任何字段发生更改或 所属的套接字组时,将记录FD_QOS或FD_GROUP_QOS网络事件。 必须通过具有SIO_GET_QOS和/或SIO_GET_GROUP_QOS的 LPWSPIoctl 函数向 Windows 套接字 SPI 客户端提供此更改,以检索套接字 的当前 QOS,或分别属于 的套接字组。

FD_ROUTING_INTERFACE_CHANGE网络事件记录在发出此类 IOCTL 后,应用于访问 WSAIoctl 中指定的目标的本地接口,SIO_ROUTING_INTERFACE_CHANGE更改

FD_ADDRESS_LIST_CHANGE网络事件是在发出SIO_ADDRESS_LIST_CHANGE的 WSAIoctl 后,Windows Sockets SPI 客户端可以绑定更改 的套接字协议系列列表时记录的。

要求

要求 价值
最低支持的客户端 Windows 10 内部版本 20348
支持的最低服务器 Windows 10 内部版本 20348
标头 ws2spi.h

另请参阅

LPWSPEnumNetworkEvents