WSASend,完成的WSARecv例行调度问题(WSASend, WSARecv completi

2019-09-17 18:48发布

我实现一个客户机/服务器对,通过TCP / IP套接字commnicating,使用重叠IO在Windows完成例程。 调试正在两个的VirtualBox虚拟机(客户端于一体,在另一台服务器)来完成。 CPU是四核。

在客户端上的操作顺序基本是:

  • 发出的WSARecv调用(将无法完成作为尚未)。
  • 问题与分组WSASend调用。 服务器将通过相同的插座发送回复。
  • 一旦执行了WSASend调用完成例程的分组放置在等待换应答队列。
  • 一旦完成例程的调用的WSARecv执行(从收到服务器应答),代码试图找到与队列中的这个答复包。
  • 发出的WSARecv调用(将无法完成作为尚未)。
  • 从第二步骤重复。

在服务器上的操作顺序基本是:

  • 发出的WSARecv调用(将无法完成作为尚未)。
  • 一旦完成例程(从客户端接收的数据包)的呼叫的WSARecv执行,在辅助线程处理的分组。
  • 发出的WSARecv调用(将无法完成作为尚未)。
  • 一旦次级线程完成的应答被发送到客户端,发出主线程上的WSASend调用。
  • 从第二步骤重复。

时遇到的问题是,有时应答客户端上接收,而不必在等待换应答队列相应的分组。 由于调试努力的一部分,我有两个问题:

1)它是可以设想,具有未决的WSARecv呼叫时,的WSARecv的完成例程定于提前完成例程用于对应WSASend(即发送到服务器回答分组)的一者的执行?

2)如果WSASend调用完成后立即仍然安排执行完成例程?

我使用的是WSAWaitForMultipleEvents电话为报警等待功能。

Answer 1:

您的代码被打破。 即使是保证了操作,以完成特定的顺序,将无法确保完成适应症在任何特定的顺序接收,或者说处理这些落成的代码将在任何特定的顺序执行。

回答你的第二个问题是肯定的 。 一般情况下,你可以把即时完成一样挂起,因为完成例程会在两种情况下运行。

您的问题,理想的解决方案是考虑包为你决定把它尽快等待回复。

如果由于某种原因,需要太多的代码修改,你有另一种选择。 如果您收到的WSARecv完成和WSASend完成尚未发生,只是推迟处理的WSARecv完成。 你可以这样做两种方式:

  1. 产生一个线程等待几分之一秒,然后重新发布该完成通知(通过调用PostQueuedCompletionStatus )从该线程。 据推测,WSASend届时将已完成。

  2. 标记了的WSARecv完成了标记和保存完成的信息。 当WSASend完成后,请注意标志和处理的WSARecv即可。 (通过直接调用完成处理程序可能)。



文章来源: WSASend, WSARecv completion routines scheduling questions
标签: sockets io