PFN_WSK_ACCEPT回调函数 (wsk.h)

WskAccept 函数接受侦听套接字上的传入连接。

语法

PFN_WSK_ACCEPT PfnWskAccept;

NTSTATUS PfnWskAccept(
  [in]            PWSK_SOCKET ListenSocket,
                  ULONG Flags,
  [in, optional]  PVOID AcceptSocketContext,
  [in, optional]  const WSK_CLIENT_CONNECTION_DISPATCH *AcceptSocketDispatch,
  [out, optional] PSOCKADDR LocalAddress,
  [out, optional] PSOCKADDR RemoteAddress,
  [in, out]       PIRP Irp
)
{...}

参数

[in] ListenSocket

指向 WSK_SOCKET 结构的指针,该结构指定正在检查传入连接的侦听或流套接字的套接字对象。

Flags

此参数保留供系统使用。 WSK 应用程序必须将此参数设置为零。

[in, optional] AcceptSocketContext

指向正在接受的套接字的调用方提供的上下文的指针。 WSK 子系统将此指针传递给接受的套接字的事件回调函数。 上下文信息对 WSK 子系统是不透明的。 上下文信息必须存储在非分页内存中。 如果 WSK 应用程序不会在接受的套接字上启用任何事件回调函数,则应将此指针设置为 NULL

[in, optional] AcceptSocketDispatch

指向常量的指针 WSK_CLIENT_CONNECTION_DISPATCH 结构。 此结构是一个调度表,其中包含指向接受套接字的事件回调函数的指针。 如果 WSK 应用程序不会为接受的套接字启用所有事件回调函数,则它应该将调度表中的指针设置为 NULL ,以便那些它未启用的事件回调函数。 如果 WSK 应用程序不会在接受的套接字上启用任何事件回调函数,则应将此指针设置为 NULL

[out, optional] LocalAddress

指向调用方分配的缓冲区的指针,该缓冲区接收传入连接到达的本地传输地址。 缓冲区必须位于非分页内存中。 缓冲区还必须足够大,以包含与 WSK 应用程序在创建侦听套接字时指定的地址系列相对应的特定 SOCKADDR 结构类型。 此指针是可选的,可以为 NULL

[out, optional] RemoteAddress

指向调用方分配的缓冲区的指针,该缓冲区接收来自传入连接的远程传输地址。 缓冲区必须位于非分页内存中。 缓冲区还必须足够大,以包含与 WSK 应用程序在创建侦听套接字时指定的地址系列相对应的特定 SOCKADDR 结构类型。 此指针是可选的,可以为 NULL

[in, out] Irp

指向调用方分配的 IRP 的指针,WSK 子系统使用该指针以异步方式完成接受操作。 有关将 IRP 与 WSK 函数配合使用的详细信息,请参阅 将 IRP 与 Winsock 内核函数配合使用

返回值

WskAccept 返回以下 NTSTATUS 代码之一:

返回代码 说明
STATUS_SUCCESS
已成功接受传入连接。 IRP 将以成功状态完成。
STATUS_PENDING
IRP 已由 WSK 子系统排队,该子系统正在等待侦听套接字上的传入连接。
STATUS_FILE_FORCED_CLOSED
套接字不再正常工作。 IRP 将以失败状态完成。 WSK 应用程序必须调用 WskCloseSocket 函数以尽快关闭套接字。
其他状态代码
出现了错误。 IRP 将以失败状态完成。

注解

WSK 应用程序可以通过调用 WskBind 函数,在以前绑定到本地传输地址的侦听套接字或流套接字上调用 WskAccept 函数。

WskAccept 函数的行为取决于传入连接是否正在等待在侦听套接字上接受:

  • 如果传入连接已到达侦听套接字并等待接受, 则 WskAccept 函数将返回STATUS_SUCCESS。 在这种情况下,IRP 以成功状态完成,IRP 的 IoStatus.Information 字段包含指向接受套接字的套接字对象的指针。
  • 如果传入连接未等待在侦听套接字上接受, WskAccept 将返回STATUS_PENDING并且 WSK 子系统将 IRP 排队,直到收到传入连接。 收到传入连接时,WSK 子系统以成功状态异步完成 IRP。 在这种情况下,IRP 的 IoStatus.Information 字段包含指向接受套接字的套接字对象的指针。
如果在侦听套接字上启用了 WSK 应用程序的 WskAcceptEvent 事件回调函数,并且应用程序在同一侦听套接字上具有对 WskAccept 函数的挂起调用,则当传入连接到达时,对 WskAccept 的挂起调用优先于 WskAcceptEvent 事件回调函数。 仅当没有 IRP 排队等待 对 WskAccept 的 调用时,WSK 子系统才调用应用程序的 WskAcceptEvent 事件回调函数。 但是,WSK 应用程序不应假定 WSK 子系统不会为具有对 WskAccept 函数 的挂起调用的侦听套接字调用 应用程序的 WskAcceptEvent 事件回调函数。 存在争用条件,WSK 子系统仍可以为套接字调用 WSK 应用程序的 WskAcceptEvent 事件回调函数。 WSK 应用程序确保 WSK 子系统不会为侦听套接字调用应用程序的 WskAcceptEvent 事件回调函数的唯一方法是在套接字上禁用应用程序的 WskAcceptEvent 事件回调函数。

WskAccept 函数成功接受传入连接时,默认禁用接受的套接字上的所有事件回调函数。 有关启用任何接受套接字的事件回调函数的详细信息,请参阅 启用和禁用事件回调函数

如果 WSK 应用程序在 LocalAddress 参数、RemoteAddress 参数或两个参数中指定非 NULL 指针,并且如果 WskAccept 返回STATUS_PENDING,则这些参数指向的缓冲区必须保持有效,直到 IRP 完成。 如果 WSK 应用程序使用 ExAllocateXxx 函数之一分配了缓冲区,则在完成 IRP 之前,它无法使用相应的 ExFreeXxx 函数释放内存。 如果 WSK 应用程序在堆栈上分配了缓冲区,则在 IRP 完成之前,它无法从调用 WskAccept 函数的函数返回。

WSK 子系统代表 WSK 应用程序为接受的连接 ( WSK_SOCKET) 分配套接字对象结构的内存。 WSK 子系统在套接字关闭时解除分配此内存。

要求

要求
最低受支持的客户端 在 Windows Vista 和更高版本的 Windows 操作系统中可用。
目标平台 通用
标头 wsk.h (包括 Wsk.h)
IRQL <= DISPATCH_LEVEL

另请参阅

SOCKADDR

WSK_CLIENT_CONNECTION_DISPATCH

WSK_PROVIDER_LISTEN_DISPATCH

WSK_PROVIDER_STREAM_DISPATCH

WSK_SOCKET

WskAcceptEvent

WskBind

WskCloseSocket

WskSocket