gpt4 book ai didi

sockets - WSASend,WSARecv完成例程安排问题

转载 作者:行者123 更新时间:2023-12-03 12:06:02 24 4
gpt4 key购买 nike

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

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

  • 发出WSARecv调用(目前尚未完成)。
  • 发出带有数据包的WSASend调用。服务器将通过同一套接字发送答复。
  • 一旦执行了WSASend调用的完成例程,则将数据包放置在等待答复队列中。
  • 一旦执行了WSARecv调用的完成例程(收到来自服务器的答复),该代码便尝试在队列中查找与此答复相关的数据包。
  • 发出WSARecv调用(目前尚未完成)。
  • 从第二步重复。

  • 服务器上的操作顺序基本上是:
  • 发出WSARecv调用(目前尚未完成)。
  • 一旦执行了WSARecv调用的完成例程(接收到来自客户端的数据包),便在辅助线程中对该数据包进行处理。
  • 发出WSARecv调用(目前尚未完成)。
  • 一旦辅助线程完成,则将答复发送给客户端,从而在主线程上发出WSASend调用。
  • 从第二步重复。

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

    1)是否可以想象,在等待WSARecv调用的情况下,将WSARecv的完成例程安排在相应WSASend(向服务器发送了数据包的那个)的完成例程之前执行?

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

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

    最佳答案

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

    您第二个问题的答案是肯定的。通常,您可以将立即完成与挂起一样对待,因为在两种情况下都将运行完成例程。

    解决您的问题的理想方法是,在您决定发送数据包后立即考虑该数据包正在等待答复。

    如果由于某种原因需要太多的代码更改,则可以选择另一种方法。如果您收到WSARecv完成,但尚未发生WSASend完成,则只需推迟处理WSARecv完成。您可以通过两种方式执行此操作:

  • 生成线程以等待一秒钟,然后从该线程重新发布完成通知(通过调用PostQueuedCompletionStatus)。据推测,WSASend将在那时完成。
  • 标记WSARecv已完成的标志并保存完成信息。 WSASend完成后,请注意该标志并随后处理WSARecv。 (可能通过直接调用完成处理程序。)
  • 关于sockets - WSASend,WSARecv完成例程安排问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10908435/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com