TCP的滑动窗口

TCP使用滑动窗口做流量控制与乱序重排

 TCP会将数据拆分成段进行发送,出于速度和效率的考虑,不可能等每一个报文段都接收到对应的ACK之后才去发送下一个,一般都是批量发送。TCP必须要解决可靠传输以及包乱序的问题,也必须考虑网络的拥塞情况,因此使用了滑动窗口机制,保证TCP的可靠性与流控特性。


tcp.png

窗口数据的计算过程

TCP缓冲区.png

 先看发送端:

  • LastByteAcked表示收到ACK的最后一个字节,根据TCP的机制,该字节之前的所有字节都是已经被接收并确认过了的。
  • LastByteSent表示已经发送但是还未收到ACK的最后一个字节。
  • LastByteWritten表示发送方应用进程已经写完的最后一个字节。

 接收端:

  • LastByteRead表示接收方应用进程已经收到、确认并且读取的最后一个字节。
  • NextByteExpected表示接收方期望收到的下一个字节(报文中ack的值)。和LastByteRcvd之间可能有间隔,表示中间还有部分字节没有收到。
  • LastByteRcvd表示接收方收到的最后一个字节。

 AdvertisedWindow的值就是接收端报文中的Window Size字段的值,MaxRcvBuffer表示接收方的最大缓冲区大小,因此接收方剩余可接收数据的大小为:
AdvertisedWindow = MaxRcvBuffer - (LastByteRcvd - LastByteRead)
 发送端在接收到Window Size字段后,结合CongestionWindow(拥塞窗口)制定自身最大的发送窗口:
MaxSenderWindow::min\{CongestionWindow, AdvertisedWindow\}
 EffectiveWindow表示发送窗口内剩余可发送的大小:
EffectiveWindow = MaxSenderWindow - (LastByteSent - LastByteAcked)

滑动窗口的工作原理(流量控制)

发送方窗口

TCP发送方滑动窗口.png

 在TCP会话过程中,发送的字节可以被分为四类:

  • 已经被发送并且收到了ACK的字节
  • 已经发送但是尚未收到ACK的字节
  • 未发送但允许发送的字节
  • 未发送且由于发送窗口限制,不允许发送的字节

 其中已经发送但是尚未收到ACK的字节和未发送但允许发送的字节,组成了发送端的滑动窗口。


TCP发送端滑动窗口工作过程.png

 只有在被连续确认之后,滑动窗口才会移动。例如,如果接收端尚未收到32-35字节,它会一直发送(ACK = 1, ack = 32), 不论是否收到了35以后的字节。一旦接收端收到32-35字节,接收端就会改变ACK报文中ack的值,发送端窗口就可以继续滑动。

接收端窗口

TCP接收端滑动窗口.png

 字节流在接收端可以被分为3类:

  • 已经接收并且已经发送ACK的字节
  • 未接收但窗口允许接收的字节
  • 未接收且窗口不允许接收的状态

 未接收但窗口允许接收的字节就是接收端的滑动窗口大小。只有在收到ack所期望的字节,窗口才会滑动。
 滑动窗口基于确认重传机制。

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容