当前位置: 首页 > 面试题库 >

什么是TCP窗口更新?

龚浩宕
2023-03-14
问题内容

我正在为Java游戏制作自己的自定义服务器软件(游戏和原始服务器软件都是用Java编写的)。没有可用的协议文档,因此我必须使用Wireshark读取数据包。

客户端连接时,服务器将以Gzip格式将其发送到级别文件。在发送大约94个数据包时,我的服务器通过ArrayIndexOutOfBoundsException使客户端崩溃。根据原始服务器的捕获文件,它大约在该点发送一个TCP窗口更新。什么是TCP窗口更新,如何使用SocketChannel发送一个?


问题答案:

TCP窗口用于连接上对等方之间的流控制。对于每个ACK数据包,主机将发送“窗口大小”字段。该字段表示主机在数据满之前可以接收多少字节的数据。发送方发送的数据量不应超过该数量。

如果客户端接收数据的速度不够快,则该窗口可能已满。换句话说,当应用程序关闭时,除了从套接字读取数据外,TCP缓冲区可能已满。发生这种情况时,客户端将发送一个“窗口已满”位设置的ACK数据包。此时,服务器应该停止发送数据。发送到具有完整窗口的计算机的任何数据包都
不会
被确认。(这将导致行为不端的发送方重新传输。行为良好的发送方将仅缓冲传出的数据。如果发送方的缓冲区也填满,则发送应用程序在尝试向套接字写入更多数据时将阻塞!)

这是一个TCP停顿。发生这种情况的原因有很多,但最终它仅意味着发送方的传输速度快于接收方的读取速度。

一旦接收端的应用程序恢复到从套接字读取数据,它将耗尽一些缓冲的数据,从而释放一些空间。然后,接收方将发送“窗口更新”数据包,以告诉发送方它可以传输多少数据。发送方开始传输其缓冲的数据,流量应正常流动。

当然,如果接收器持续缓慢,您可能会反复停顿。

我说的这句话好像发送方和接收方不同,但实际上,两个对等方都在与每个ACK数据包交换窗口更新,并且任何一方都可以填充其窗口。

总的信息是您不需要直接发送窗口更新数据包。欺骗一个人实际上不是一个好主意。

关于您看到的异常……它不太可能是由窗口更新数据包引起或阻止的。但是,如果客户端读取速度不够快,则可能会丢失数据。在服务器中,应检查Socket.write()调用的返回值。它可能少于您要写入的字节数。如果发送方的发送缓冲区已满,则会发生这种情况,这可能在TCP停顿期间发生。您可能正在丢失字节。

例如,如果您尝试在每次调用时写入8192字节,但是其中一个调用返回5691,则您需要在下一个调用中发送剩余的2501字节。否则,客户端将看不到该8K块的其余部分,并且您的文件在客户端比在服务器端短。



 类似资料:
  • 下面是我在连接末尾看到的数据包序列(需要更多数据): 接收者在21:24:43重新打开窗户,再也没有听到发送者的声音。一分钟后,接收器超时连接(关闭由应用程序启动),并发送一系列未确认的FIN-ACK。 看起来与发送方的通信就这样丢失了(捕获是在接收方的网络上进行的)。如果不是,那么是否应该一直期待对Fin-ACK的确认,即使在一段足够长的时间使对等体忘记了连接之后也是如此?

  • 问题内容: 运行以下代码: 结果是: 上面的代码中没有定义任何窗口框架,它看起来默认的窗口框架是 不确定我对默认窗口框架的理解是否正确 问题答案: 从Spark Gotchas 默认帧规格取决于给定窗口定义的其他方面: 如果指定了ORDER BY子句,并且该函数接受了帧规范,则该帧规范是由RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW定义的, 否

  • 问题内容: 我读苹果文档 ,当我发现这句话: 本类仅包含一个属性:。 此属性存储对应用程序窗口的引用。此窗口表示应用程序视图层次结构的根。这 是绘制所有应用程序内容的地方。请注意,window属性是 可选的 ,这意味着 在某些时候它可能没有任何值(为nil ) 。 我不明白的是:为什么此属性有时可能为零? 变成零的情况是什么? 问题答案: 当您关闭应用程序时,您的应用程序仍可以接收静默通知 或在后

  • 介绍 将TCP与UDP这样的简单传输协议区分开来的是它传输数据的质量。TCP对于发送数据进行跟踪,这种数据管理需要协议有以下两大关键功能: 可靠性:保证数据确实到达目的地。如果未到达,能够发现并重传。 数据流控:管理数据的发送速率,以使接收设备不致于过载。 要完成这些任务,整个协议操作是围绕滑动窗口确认机制来进行的。因此,理解了滑动窗口,也就是理解了TCP。 更多信息 TCP面向流的滑动窗口确认机

  • 介绍 前文已经介绍过了TCP滑动窗口大小的重要性。在客户端与服务器的连接中,客户端告知服务器它一次希望从服务器接收多少字节数据,这是客户端的接收窗口,即服务器的发送窗口。类似地,服务器告知客户端一次希望从客户端接收多少字节数据,也就是服务器的接收窗口和客户端的发送窗口。 要理解为什么窗口大小会产生波动,首先需要理解它的含义。最简单的方式是它代表了设备对于特定连接的接收缓存大小。即,窗口大小代表一个

  • 关于一些JMX度量的文档提到了一个时间窗口,在这个时间窗口上对一些度量进行平均。 例如:https://docs.confluent.io/current/kafka/monitoring.html 这个时间窗口是什么?是固定的、可配置的,还是动态调整的? 谢谢你的帮助。