PFN_WSK_RECEIVE_EVENT回调函数 (wsk.h)
WskReceiveEvent 事件回调函数通知 WSK 应用程序已收到面向连接的套接字上的数据。
语法
PFN_WSK_RECEIVE_EVENT PfnWskReceiveEvent;
NTSTATUS PfnWskReceiveEvent(
[in, optional] PVOID SocketContext,
[in] ULONG Flags,
[in, optional] PWSK_DATA_INDICATION DataIndication,
[in] SIZE_T BytesIndicated,
[in, out] SIZE_T *BytesAccepted
)
{...}
参数
[in, optional] SocketContext
指向已接收数据的面向连接的套接字的套接字上下文的指针。 WSK 应用程序通过以下方式之一向 WSK 子系统提供了此指针:
- 它调用 WskSocket 函数来创建套接字。
- 它调用 WskSocketConnect 函数来创建套接字。
- 它调用 WskAccept 函数以接受套接字作为传入连接。
- 其 WskAcceptEvent 事件回调函数被调用以接受套接字作为传入连接。
[in] Flags
包含以下标志组合的按位 OR 的 ULONG 值:
价值 | 意义 |
---|---|
|
如果可能,WSK 应用程序不应保留包含已接收数据的数据缓冲区。 如果 WSK 应用程序保留缓冲区,应通过调用 WskRelease 函数来尽快释放缓冲区。 |
|
数据缓冲区包含整个消息或消息的最后部分。 构成整个消息的解释特定于传输协议。 对于 TCP,此标志指示为构成数据缓冲区中数据的一个或多个 TCP 段设置了推送位。 |
|
在 IRQL = DISPATCH_LEVEL 上调用 WskReceiveEvent 的 WSK 子系统 事件回调函数。 如果未设置此标志,WSK 子系统可能会在任何 IRQL <= DISPATCH_LEVEL调用 WskReceiveEvent 事件回调函数。 |
[in, optional] DataIndication
指向描述接收数据的 WSK_DATA_INDICATION 结构链接列表的指针。 如果此参数 NULL,则套接字不再正常工作,并且 WSK 应用程序必须调用 WskCloseSocket 函数才能尽快关闭套接字。
[in] BytesIndicated
WSK_DATA_INDICATION 结构链接列表描述的接收数据的字节数。
[in, out] BytesAccepted
指向SIZE_T类型的变量的指针,该变量接收 WSK 应用程序接受的接收数据的字节数。 仅当 WSK 应用程序接受已接收数据的字节总数的一部分时,才需要设置此变量。 如果 WSK 应用程序接受所有接收的数据,则无需设置此变量。 如果 WskReceiveEvent 事件回调函数返回STATUS_SUCCESS以外的状态,则 WSK 子系统将忽略此变量的值。
返回值
WSK 应用程序的 WskReceiveEvent 事件回调函数可以返回以下 NTSTATUS 代码之一:
返回代码 | 描述 |
---|---|
|
WSK 应用程序至少接受了一些收到的数据。 如果 WSK 应用程序接受所有接收的数据,WSK 子系统可以在套接字上收到新数据时再次调用 WskReceiveEvent 事件回调函数。 但是,如果 WSK 应用程序只接受接收数据的一部分,WSK 子系统将不会再次调用 WskReceiveEvent 事件回调函数,直到 WSK 应用程序调用 WskReceive 函数之后。 WSK 应用程序调用 WskReceive 函数后,WSK 子系统将恢复调用 WskReceiveEvent 事件回调函数以及套接字上收到新数据时。 WSK 应用程序可以使用零长度缓冲区调用 WskReceive 函数,这将导致 WSK 子系统恢复调用 WskReceiveEvent 事件回调函数,而无需调用 WskReceive 来接收套接字中的任何数据。 |
|
WSK 应用程序接受了数据,但未检索 WSK_DATA_INDICATION 结构链接列表中包含的所有数据。 WSK 应用程序将保留WSK_DATA_INDICATION结构的链接列表,直到检索到所有数据。 在 WSK 应用程序检索到所有数据后,它调用 WskRelease 函数,以将WSK_DATA_INDICATION结构的链接列表释放回 WSK 子系统。 当套接字上收到新数据时,WSK 子系统可以再次调用 WskReceiveEvent 事件回调函数。 |
|
WSK 应用程序不接受数据。 在这种情况下,WSK 子系统将具有基础传输缓冲区(如果可能)或协议需要的基础传输缓冲区。 WSK 子系统不会再次调用 WskReceiveEvent 事件回调函数,直到 WSK 应用程序调用 WskReceive 函数。 WSK 应用程序调用 WskReceive 函数后,WSK 子系统将恢复调用 WskReceiveEvent 事件回调函数以及套接字上收到新数据时。 WSK 应用程序可以使用零长度缓冲区调用 WskReceive 函数,这将导致 WSK 子系统恢复调用 WskReceiveEvent 事件回调函数,而无需调用 WskReceive 来接收套接字中的任何数据。 |
言论
仅当以前使用 SO_WSK_EVENT_CALLBACK 套接字选项启用事件回调函数时,WSK 子系统才会调用 WSK 应用程序的 WskReceiveEvent 事件回调函数。 有关启用套接字的事件回调函数的详细信息,请参阅 启用和禁用事件回调函数。
如果 WSK 应用程序的 WskReceiveEvent 事件回调函数在面向连接的套接字上启用,并且应用程序还对同一连接导向套接字上的 WskReceive 函数具有挂起调用, 然后,当数据到达时,对 WskReceive 函数的挂起调用将优先于 WskReceiveEvent 事件回调函数。 仅当没有从挂起调用到 WskReceive 函数的 IRP 时,WSK 子系统才会调用应用程序的 WskReceiveEvent 事件回调函数。 但是,WSK 应用程序不应假定 WSK 子系统不会调用应用程序的 WskReceiveEvent 事件回调函数,该套接字具有对 WskReceive 函数的挂起调用。 存在争用条件,其中 WSK 子系统仍可以调用 WSK 应用程序的 WskReceiveEvent 套接字的事件回调函数。 WSK 应用程序确保 WSK 子系统不会为面向连接的套接字调用应用程序的 WskReceiveEvent 事件回调函数的唯一方法是禁用应用程序的 WskReceiveEvent 套接字上的事件回调函数。
注意
Winsock 内核 (WSK) 以串行方式调用此回调,因此在收到数据后,它并不总是被调用。
WSK 子系统在 IRQL <= DISPATCH_LEVEL 调用 WSK 应用程序的 WskReceiveEvent 事件回调函数。
WSK 应用程序的 WskReceiveEvent 事件回调函数不得等待 WSK 完成或事件回调函数上下文中的其他 WSK 请求的完成。 回调可以启动其他 WSK 请求(假设它在DISPATCH_LEVEL花费的时间不太多),但即使在 IRQL = PASSIVE_LEVEL调用回调,它也不能等待完成。
要求
要求 | 价值 |
---|---|
最低支持的客户端 | 在 Windows Vista 和更高版本的 Windows作系统中可用。 |
目标平台 | 窗户 |
标头 | wsk.h (包括 Wsk.h) |
IRQL | <= DISPATCH_LEVEL |