WSASend,WSARecv完成例程调度问题 [英] WSASend, WSARecv completion routines scheduling questions

查看:143
本文介绍了WSASend,WSARecv完成例程调度问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm implementing a client/server pair, commnicating through TCP/IP sockets, using overlapped IO with completion routines in Windows. The debugging is being done with two VirtualBox virtual machines (client in one, server in another). The CPU is a Quad-Core.

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

The sequence of operations on the client is basically:


  • 发出WSARecv调用(目前尚未完成)。

  • 使用数据包发出WSASend调用。服务器将通过同一个套接字发送回复。

  • 执行WSASend调用的完成例程后,数据包将被置于等待回复队列中。

  • 一旦执行了WSARecv调用的完成例程(收到服务器的回复),代码就会尝试在队列中找到与此回复相关的数据包。

  • 发布一个WSARecv调用(尚未完成)。

  • 从第二步开始重复。

  • Issues a WSARecv call (will not complete as of yet).
  • Issues a WSASend call with a packet. The server will send a reply through the same socket.
  • Once the completion routine for the WSASend call is executed the packet is placed in a waiting-for-reply queue.
  • Once the completion routine for the WSARecv call executes (reply from server received), the code tries to locate the packet related to this reply in the queue.
  • Issues a WSARecv call (will not complete as of yet).
  • Repeat from the second step.

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

The sequence of operations on the server is basically:


  • 发出WSARecv调用(目前尚未完成)。

  • 一旦WSARecv调用的完成例程执行(来自客户端收到的数据包),就会在辅助线程中处理该数据包。

  • 发出一个WSARecv调用(将尚未完成。)

  • 一旦辅助线程完成,回复将被发送到客户端,在主线程上发出WSASend调用。

  • 重复从第二步开始。

  • Issues a WSARecv call (will not complete as of yet).
  • Once the completion routine for the WSARecv call executes (packet from the client received), the packet in processed in a secondary thread.
  • Issues a WSARecv call (will not complete as of yet).
  • Once the secondary thread completes a reply is sent to the client, issuing a WSASend call on the primary thread.
  • Repeat from the second step.

我遇到的问题是,有时会在客户端收到回复而没有相应的数据包等待回复队列。作为调试工作的一部分,我有两个问题:

The problem I'm having is that sometimes a reply is received on the client without having a corresponding packet in the waiting-for-reply queue. As part of the debugging effort I have two questions:

1)可以想象,有一个挂起的WSARecv调用,WSARecv的完成例程被安排提前执行相应WSASend的完成例程(发送服务器回复的数据包的那个)?

1) Is it conceivable that, having a pending WSARecv call, the completion routine of the WSARecv is scheduled for execution ahead of the completion routine for the corresponding WSASend (the one that sent the packet to which the server replied) ?

2)如果WSASend调用立即完成,则完成例程仍然是计划执行?

2) If a WSASend call completes immediately is the completion routine still scheduled for execution ?

我正在使用WSAWaitForMultipleEvents调用作为警报等待函数。

I'm using a WSAWaitForMultipleEvents call as the alertable wait function.

推荐答案

您的代码已损坏。即使操作保证以特定顺序完成,也不能确保以任何特定顺序接收完成指示,或者处理这些完成的代码将以任何特定顺序运行。

Your code is broken. Even if the operations were guaranteed to complete in a particular order, that would not ensure that the completion indications were received in any particular order or that the code that handles those completions will run in any particular order.

第二个问题的答案是。通常,您可以将立即完成视为待处理,因为完成例程将在任何一种情况下运行。

The answer to your second question is yes. Generally, you can treat immediate completion the same as pending, since the completion routine will run in either case.

您的问题的理想解决方案是将数据包视为在您决定发送它后立即等待回复。

The ideal solution to your problem is to consider the packet to be waiting for reply as soon as you decide to send it.

如果出于某种原因需要更多代码更改,您还有另一种选择。如果您收到WSARecv完成并且尚未完成WSASend完成,则只需延迟处理WSARecv完成。您可以通过以下两种方式执行此操作:

If for some reason that requires too many code changes, you have another choice. If you receive a WSARecv completion and the WSASend completion has not occurred yet, simply defer processing the WSARecv completion. You can do this two ways:


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

  1. Spawn a thread to wait a fraction of a second and then re-post the completion notification (by calling PostQueuedCompletionStatus) from that thread. Presumably, the WSASend will have completed by then.

标记WSARecv已完成的标志并保存完成信息。当WSASend完成时,请注意该标志并处理WSARecv。 (可能直接调用完成处理程序。)

Mark a flag that the WSARecv has completed and save the completion information. When the WSASend completes, notice that flag and process the WSARecv then. (Possibly by calling the completion handler directly.)

这篇关于WSASend,WSARecv完成例程调度问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆