【问题标题】:Optimized process for receiving data packets during heavy network load [closed]网络负载较重时接收数据包的优化流程[关闭]
【发布时间】:2014-08-20 10:29:39
【问题描述】:

我正在用 C++ 编写客户端-服务器应用程序(TCP 协议)。
我有可能客户端可以从多个服务器接收数据。
为了解决这个问题,我创建了一个套接字连接列表。

在一个循环中,在每个套接字上,我执行以下操作:

  • 尝试在套接字上接收有关此的数据
  • 把它放在缓冲区中
  • 处理缓冲区数据
  • 清除缓冲区
  • 对下一个套接字执行相同的步骤

现在在我的设计中,最初我为所有连接创建了一个公共缓冲区。但我建议在网络负载过重的情况下,收到的电报可能不是完整的电报,它可能是电报的一部分。所以要完成一个电报,我将不得不等待下一次迭代相同的套接字,甚至俱乐部/识别电报将是一个复杂的过程。

要处理这种情况,一种解决方案可能是为每个连接提供专用缓冲区。

任何人都可以提出更优化/更好的解决方案来避免为每个连接创建专用缓冲区吗?

【问题讨论】:

  • 看看 Boost Asio boost.org/doc/libs/1_55_0/doc/html/boost_asio.html 这样您就不必重新发明轮子了。一般来说,如果您需要能够保存部分数据的实例,则需要为此设置一个缓冲区。另请注意,网络堆栈将为您缓冲 TCP 数据,因此取决于您的确切要求,可能就足够了。
  • “没有收到完整的电报”问题并不是重负载所独有的。你也会在轻负载时遇到这个问题。 TCP 套接字流一直接收部分数据 - 这是 TCP 的本质(通过分段、分段、网络上的打嗝等)。在任何情况下,您总是希望在每个套接字上循环,直到收到完整的消息。
  • @selbie:很好,同样:如果您发送两条消息,它们可能会通过一次调用recvread 来接收。归根结底,TCP 是一个具有流量控制的 字节流 协议,您必须为阻塞和/或部分发送以及部分/合并接收做好准备。
  • 据我从所有 cmets 和答案中了解到,每个连接的缓冲区是解决此问题的唯一方法。

标签: c++ tcp network-programming tcpclient


【解决方案1】:

如果您对此很认真,您会为每个套接字使用一个线程,每个线程都有自己的缓冲区,也可能进行处理或将其传递给特定于连接的处理线程,但您也可以发送所有传入数据如果出于某种原因需要连续完成,则添加到单个“工作”队列。

如果您必须使用单个线程,那么您必须为每个连接使用一个缓冲区。 TCP 实现了一种流量控制,这意味着发送方甚至可能不允许发送更多消息,直到接收方消耗足够多的消息。如果您担心内存使用情况,您可以删除已完全处理的特定于连接的缓冲区,并且仅在检测到不完整的消息时重新创建它们,但通常最近未访问的页面将在内存紧张的情况下被换出因此保留内存几乎没有什么坏处——只要您的(虚拟)地址空间充足:与重复动态内存分配和释放相关的时间和碎片可能比内存使用峰值还要糟糕。

【讨论】:

    【解决方案2】:

    我认为,如果您只想在一次将所有消息/电报全部存储在内存中时处理整个消息/电报,那么每个 TCP 连接的专用接收缓冲区将是唯一的方法。除非您的可用 RAM 数量非常有限,或者传入的消息非常大,否则这应该不是问题。 (如果有问题,请考虑使消息更小的方法;例如,将每条消息分解成一系列较小的消息,然后依次处理)

    【讨论】:

      猜你喜欢
      • 2012-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-28
      • 1970-01-01
      • 2013-03-03
      • 1970-01-01
      相关资源
      最近更新 更多