WSARecv() return 数据能立马出来吗?

Can WSARecv() return data immediately?

调用WSARecv()时,是否可以不经过完成端口阶段,立即返回数据。在 WSARecv() 文档中,它针对 lpNumberOfBytesRecvd 参数说:

A pointer to the number, in bytes, of data received by this call if the receive operation completes immediately.

是的,这并不罕见。请记住,数据以 IP 数据包的形式到达,其边界通常与您的读取不一致。如果您的 WSARecv 调用从 OS 已经保存的数据包中请求数据,则没有必要延迟并且 Windows 可能会立即 return 它。

当一个重叠的 WSARecv()IO_PENDINGSUCCESS 完成时,一个完成数据包将排队到 IOCP,请参阅 this MSDN article for details

对于 Vista 或更高版本,您可以通过为套接字调用 SetFileCompletionNotificationModes() 并传递 FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 来更改此设置(请注意,您可以在文档中将文件读作套接字,文件句柄的概念直接翻译到插座)。

如果您确实启用了完成端口跳过,那么当 WSARecv() return 立即与数据一起发送时(即 SUCCESS return 而不是 IO_PENDING return) 然后你必须直接在 WSARecv() 调用站点处理它,因为你不会得到完成数据包。

请注意,启用 "skip completion port" 处理对于减少上下文切换非常有用,但您现在需要直接或在正常的完成处理程序中处理完成。