【问题标题】:TCP Server sends [ACK] followed by [PSH,ACK]TCP 服务器发送 [ACK] 后跟 [PSH,ACK]
【发布时间】:2021-01-13 14:41:27
【问题描述】:

我正在使用高性能 TCP 服务器,当我使用 TCP 客户端泵送高流量时,我发现服务器的处理速度不够快。经过仔细检查,我看到 TCP 服务器上的“增量时间”出现峰值。而且,我看到服务器发送一个 ACK​​ 并在 0.8 秒后为相同的 seqno 发送 PSH,ACK。我在 pcap 中多次看到这种模式。专家能否评论一下为什么服务器发送一个 ACK​​ 后跟一个 PSH,ACK 之间有延迟?

TCP SERVER PCAP

【问题讨论】:

  • 听起来实际问题是I see the server not processing fast enough on and off when I pump high traffic using a TCP client. 虽然我会告诉你添加更多细节,但堆栈溢出侧重于编程问题,所以你应该问这个 expanded 问题服务器故障或 networkengineering.stackexchange.com(如果您是网络专业人士)。
  • 在第 95182 帧中,客户端发送 1244 个字节,序列号为 87918542。在第 95183 帧中,服务器 ACKs 87918542+1244=87919786。下一个帧 95184 服务器发送 315 个字节,并且由于除了初始 SYN 之外的每个段都设置了 ACK 标志,它用 87919786 填充 seq,因为它没有从客户端收到任何额外的数据。 PSH 标志提示客户端 TCP 堆栈立即将数据传递给应用程序,这表明 315 字节是服务器对套接字的一次写入。
  • @JimD。感谢您的详细分析。它有助于清除我的一些问题。所以,如果我理解正确的话,帧 95183 和 95184 之间 0.8 秒的“增量时间”表明客户端没有正确地向服务器发送任何数据?在这种情况下,客户端有一个繁忙的循环要写入 SSL 套接字。
  • 请注意,第 95182 帧不是完整帧,并且设置了 PSH,因此这很可能是写入套接字的完整有效负载。 95182 中的数据在 95183 中被确认。然后我们在 0.8 秒内看到捕获中没有数据,然后服务器回复 513 个字节。如果客户端正忙于写入套接字,为什么我们在 0.8 秒内看不到更多数据? recvq 中有足够的空间,从捕获中没有明显的原因导致它不会继续发送。
  • @JimD。好点!服务器上的 GC 暂停会导致此问题吗?还是您认为这肯定表明客户端没有向套接字写入任何内容。

标签: networking tcp wireshark pcap tcpdump


【解决方案1】:

为了简化 ACKPSH 的含义

  • ACK 将始终存在,它只是通知客户端服务器最后收到的字节是什么。
  • PSH 告诉客户端/服务器将字节推送到应用层(字节形成完整的消息)。

您习惯的通常情况或多或少如下:

  1. 操作系统有一个缓冲区,用于存储从客户端接收到的数据。
  2. 一旦收到数据包,就会将其添加到缓冲区中。
  3. 应用程序调用套接字接收方法并从缓冲区中取出数据
  4. 应用程序将数据写回套接字(响应)
  5. 操作系统发送一个带有标志PSH,ACK的数据包

现在想象一下这些场景:

  • 第 4 步没有发生(应用程序没有写回任何数据,或者写的时间太长)

    => 操作系统只使用ACK 确认接收(数据包中不会包含任何数据),如果应用程序稍后决定发送某些内容,它将使用PSH,ACK 发送。

  • 服务器发送的消息/数据太大,无法放入一个数据包中:

    • 第一个数据包没有PSH标志,只有ACK标志
    • 最后一个数据包将带有标志PSH,ACK,以通知消息结束。

【讨论】:

  • 感谢您的回答!您能否澄清接下来的事情,以免产生类似的问题。第一个问题,我是否正确理解包含消息最后一部分的 tcp-segment 始终设置了 PSH 标志?我知道有设置 PSH 标志的示例,但消息未在最后一段完成。第二个问题,是否存在最后接收到的段包含先前消息的部分和新消息的字节的情况?提前致谢。
  • 包含消息最后一部分的tcp-segment总是设置了PSH标志?是的
  • 是否存在最后收到的段包含上一条消息的部分和新消息的字节的情况?我没有看到它在实践中发生。
  • 我不确定第二个问题,因为章节:2.8。数据通信 (rfc793)。引用:“任何特定段中的数据可能是单个 SEND 调用(全部或部分)或多个 SEND 调用的结果。”我是否正确理解一个片段可以涵盖以下情况:{ >= 1 个消息 }、{ >=1 个消息、part-of-new-message}、{ part-of-prev-msg、>=1 个新消息, 新消息的一部分}。
猜你喜欢
  • 2019-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-26
  • 2019-08-02
相关资源
最近更新 更多