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

一个 ULONG 值,该值包含以下标志的组合的按位 OR:

含义
WSK_FLAG_RELEASE_ASAP
如果可能,WSK 应用程序不应保留包含已接收数据的数据缓冲区。 如果 WSK 应用程序保留缓冲区,则应通过调用 WskRelease 函数尽快释放它们。
WSK_FLAG_ENTIRE_MESSAGE
数据缓冲区包含整个消息或消息的最后一部分。 对构成整个消息的内容的解释是特定于传输协议的。 对于 TCP,此标志指示已为构成数据缓冲区中的数据的一个或多个 TCP 段设置了推送位。
WSK_FLAG_AT_DISPATCH_LEVEL
WSK 子系统在 IRQL = DISPATCH_LEVEL调用 WskReceiveEvent 事件回调函数。 如果未设置此标志,则 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 代码之一:

返回代码 说明
STATUS_SUCCESS
WSK 应用程序至少接受了一些收到的数据。 如果 WSK 应用程序接受了所有接收的数据,当在套接字上收到新数据时,WSK 子系统可以再次调用 WskReceiveEvent 事件回调函数。 但是,如果 WSK 应用程序只接受已接收数据的一部分,则在 WSK 应用程序调用 WskReceive 函数之前,WSK 子系统不会再次调用 WskReceiveEvent 事件回调函数。 在 WSK 应用程序调用 WskReceive 函数后,WSK 子系统将恢复调用 WskReceiveEvent 事件回调函数,其中包含任何剩余的缓冲数据,并在套接字上收到新数据时。 WSK 应用程序可以使用零长度缓冲区调用 WskReceive 函数,这将导致 WSK 子系统继续调用 WskReceiveEvent 事件回调函数,而无需调用 WskReceive 来接收来自套接字的任何数据。
STATUS_PENDING
WSK 应用程序接受数据,但未检索 WSK_DATA_INDICATION 结构链接列表中包含的所有数据。 WSK 应用程序会保留WSK_DATA_INDICATION结构的链接列表,直到检索到所有数据。 WSK 应用程序检索所有数据后,它会调用 WskRelease 函数,将WSK_DATA_INDICATION结构的链接列表释放回 WSK 子系统。 在套接字上收到新数据时,WSK 子系统可以再次调用 WskReceiveEvent 事件回调函数。
STATUS_DATA_NOT_ACCEPTED
WSK 应用程序不接受数据。 在这种情况下,WSK 子系统将让基础传输缓冲区来缓冲数据(如果可能),或者如果协议另有要求。 在 WSK 应用程序调用 WskReceive 函数之前,WSK 子系统不会再次调用 WskReceiveEvent 事件回调函数。 在 WSK 应用程序调用 WskReceive 函数后,WSK 子系统将恢复调用 WskReceiveEvent 事件回调函数,其中包含任何剩余的缓冲数据,并在套接字上收到新数据时。 WSK 应用程序可以使用零长度缓冲区调用 WskReceive 函数,这将导致 WSK 子系统继续调用 WskReceiveEvent 事件回调函数,而无需调用 WskReceive 来接收来自套接字的任何数据。

注解

仅当在面向连接的套接字上收到新数据时,WSK 子系统才调用 WSK 应用程序的 WskReceiveEvent 事件回调函数,前提是事件回调函数以前是使用 SO_WSK_EVENT_CALLBACK 套接字选项启用的。 有关启用套接字的事件回调函数的详细信息,请参阅 启用和禁用事件回调函数

如果在面向连接的套接字上启用了 WSK 应用程序的 WskReceiveEvent 事件回调函数,并且该应用程序在同一面向连接的套接字上也具有对 WskReceive 函数的挂起调用,则当数据到达时,对 WskReceive 函数的挂起调用将优先于 WskReceiveEvent 事件回调函数。 仅当 WskReceive 函数的挂起调用没有 IRP 排队时,WSK 子系统才调用应用程序的 WskReceiveEvent 事件回调函数。 但是,WSK 应用程序不应假定 WSK 子系统不会为具有对 WskReceive 函数的挂起调用的面向连接的套接字调用 应用程序的 WskReceiveEvent 事件回调函数。 存在争用条件,其中 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 操作系统中可用。
目标平台 Windows
标头 wsk.h (包括 Wsk.h)
IRQL <= DISPATCH_LEVEL

另请参阅

WSK_CLIENT_CONNECTION_DISPATCH

WSK_DATA_INDICATION

WskAccept

WskAcceptEvent

WskCloseSocket

WskReceive

WskRelease

WskSend

WskSocket

WskSocketConnect