阻塞模式下的 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 时,我应该何时释放缓冲区?
如果线程没有失去任何监视器的所有权,它是不是会导致其他正在运行的线程被阻塞