阻塞模式下的 WSASend() 是不是会导致将通知数据包放置在完成端口中?

Posted

技术标签:

【中文标题】阻塞模式下的 WSASend() 是不是会导致将通知数据包放置在完成端口中?【英文标题】:Does WSASend() in blocking mode causes a notification packet to be placed in the completion port?阻塞模式下的 WSASend() 是否会导致将通知数据包放置在完成端口中? 【发布时间】:2015-02-25 22:12:11 【问题描述】:

如果我在调用 WSASend() 时不提供重叠结构或完成例程,我可以在阻塞模式下使用它。但我的问题是:阻塞的WSASend() 调用是否会导致将通知数据包放置在完成端口中?

【问题讨论】:

【参考方案1】:

问题格式不正确。在您之前的问题中,我们已经多次讨论过这一切,例如here。要么没有完成例程,也没有重叠结构,在这种情况下也没有完成数据包,或者在这种情况下,你根本没有处于阻塞模式,你处于异步模式。

【讨论】:

这与我之前的问题无关!我说的是与完成端口关联的套接字,但我想在阻塞模式下使用WSASend(),而在重叠模式下使用WSARecv() 因此,如果没有完成例程/重叠结构,则没有完成包。这肯定是显而易见的吗?。 是的,我知道,但我认为套接字记录了它与完成端口相关联的信息。 因为没有什么可记录的。请参阅先前答案中发布的摘录。 在阻塞模式下调用WSASend()而在重叠模式下使用WSARecv()是否有问题?【参考方案2】:

如果您的套接字注册到完成端口,您可以仍然通过将NULL 传递给完成例程和OVERLAPPED 结构参数来进行阻塞调用。而且您不会收到通知(即使您的套接字已使用完成端口注册)。但是不知道是否建议同时使用WSASend()在阻塞模式和WSARecv()在重叠模式。

【讨论】:

如果您没有提供完成例程或OVERLAPPED 结构,如何接收通知。需要其中一个来提供通知。所以你的答案是正确的,你不会收到通知。 在设计中使用对WSARecv() 的阻塞调用很有用,该设计可以最大限度地减少锁定页面的数量,这对于最大化您可以支持的并发连接数很有用(更旧的更是如此操作系统)。在这种情况下,您将发布“零字节”重叠WSARecv()s,然后当这些完成时您可以发布阻塞WSARecv() 以检索您知道将立即可用的数据。有关详细信息,请参阅 Microsoft Windows 网络编程(第 2 版)。 @Len Holgate:感谢您在第一条评论中提供的信息,我编辑了我的答案。 请参考我的第一条评论。编辑不会让您的问题变得不那么奇怪。如果您没有提供OVERLAPPED 结构,您希望如何通过 IOCP 向您报告完成?由于重叠结构是重叠 I/O 操作的唯一“每个操作”数据,因此如果您没有重叠结构,则无法将启动操作的 API 调用与该操作的完成相匹配。因此,如果您没有将重叠结构传递给原始 API 调用,则不可能完成。

以上是关于阻塞模式下的 WSASend() 是不是会导致将通知数据包放置在完成端口中?的主要内容,如果未能解决你的问题,请参考以下文章

在重叠模式下使用 WSASend 时,我应该何时释放缓冲区?

信号中断阻塞模式下的发送方法

在异步函数上调用结果是不是会导致无限期阻塞?

如果线程没有失去任何监视器的所有权,它是不是会导致其他正在运行的线程被阻塞

WSASend() 和 WSARecv() 的所有错误代码是不是意味着套接字已断开连接?

使用带有选择器的非阻塞模式下的 Java NIO 和 Unix 域套接字