我正在实现一个客户端/服务器对,通过TCP / IP套接字进行通信,使用重叠的IO和Windows中的完成例程。调试是使用两个VirtualBox虚拟机完成的(客户端在一个,服务器在另一个中)。 CPU是四核的。
客户端的操作顺序基本上是:
服务器上的操作顺序基本上是:
我遇到的问题是,有时在客户端上收到回复,而在等待回复队列中没有相应的数据包。作为调试工作的一部分,我有两个问题:
1)可以想象,在挂起WSARecv调用的情况下,WSARecv的完成例程被安排在相应WSASend(发送服务器回复的数据包的那个)的完成例程之前执行吗? / p>
2)如果WSASend调用立即完成,那么仍然计划执行完成例程吗?
我正在使用WSAWaitForMultipleEvents调用作为可警告的等待函数。
答案 0 :(得分:1)
您的代码已损坏。即使操作保证以特定顺序完成,也不能确保以任何特定顺序接收完成指示,或者处理这些完成的代码将以任何特定顺序运行。
第二个问题的答案是是。通常,您可以将立即完成视为待处理,因为完成例程将在任何一种情况下运行。
解决问题的理想方法是在您决定发送数据包后立即考虑等待回复。
如果由于某种原因需要更改代码,您还有另一种选择。如果您收到WSARecv完成并且尚未完成WSASend完成,则只需延迟处理WSARecv完成。你可以这两种方式:
产生一个线程等待几分之一秒,然后从该线程重新发布完成通知(通过调用PostQueuedCompletionStatus
)。据推测,WSASend将在那时完成。
标记WSARecv已完成的标志并保存完成信息。当WSASend完成时,请注意该标志并处理WSARecv。 (可能直接调用完成处理程序。)