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 套接字 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 套接字 SPI 客户端的网络事件和关联的事件对象的规范成功,则返回值为零。 否则,将返回 值SOCKET_ERROR ,并在 lpErrno 中提供特定的错误号。

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

注解

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

LPWSPEventSelect 的运行方式与 LPWSPAsyncSelect 非常相似,区别在于发生指定网络事件时采取的操作。 WSPAsyncSelect 会导致发布 Windows 套接字 SPI 客户端指定的 Windows 消息,而 LPWSPEventSelect 设置关联的事件对象,并将此事件的发生记录在内部网络事件记录中。 Windows 套接字 SPI 客户端可以使用 LPWSPEnumNetworkEvents 检索内部网络事件记录的内容,从而确定发生了哪些指定的网络事件。

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

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

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

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 关联和网络事件选择集都适用于接受的套接字。 例如,如果侦听套接字具有 hEventObject 与 FD_ACCEPT、FD_READ 和 FD_WRITE 的 LPWSPEventSelect 关联,则该侦听套接字上接受的任何套接字也将具有与同一 hEventObject 关联的FD_ACCEPT、FD_READ和FD_WRITE网络事件。 如果需要不同的 hEventObject 或网络事件,则 Windows 套接字 SPI 客户端应调用 LPWSPEventSelect,传递接受的套接字和所需的新信息。

成功记录网络事件的发生并向关联的事件对象发出信号后,在 Windows 套接字 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 套接字 SPI 客户端由事件驱动,同时不担心任何时间到达的数据量。 考虑以下序列。

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

使用这些语义,Windows 套接字 SPI 客户端无需读取所有可用数据即可响应FD_READ网络事件。 相反,应使用单个 LPWSPRecv 来响应每个FD_READ网络事件。

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

FD_ROUTING_INTERFACE_CHANGE和FD_ADDRESS_LIST_CHANGE事件也被视为 边缘触发 事件。 当 Windows 套接字 SPI 客户端发出带有相应SIO_ROUTING_INTERFACE_CHANGE或SIO_ADDRESS_LIST_CHANGE的 WSAIoctl 请求通知后发生更改,消息将恰好发布一次。 在 Windows 套接字 SPI 客户端重新发出 IOCTL 检测到自发出 IOCTL 以来的另一个更改之前,不会再收到其他消息。

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

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

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

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

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

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

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

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

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

WSAIoctl 与 SIO_ADDRESS_LIST_CHANGE 发出 WSAIoctl 后,当 Windows 套接字 SPI 客户端可以将更改绑定到的套接字协议系列的地址列表,将记录FD_ADDRESS_LIST_CHANGE网络事件。

要求

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

另请参阅

LPWSPEnumNetworkEvents