TCP使用滑动窗口做流量控制与乱序重排
TCP会将数据拆分成段进行发送,出于速度和效率的考虑,不可能等每一个报文段都接收到对应的ACK之后才去发送下一个,一般都是批量发送。TCP必须要解决可靠传输以及包乱序的问题,也必须考虑网络的拥塞情况,因此使用了滑动窗口机制,保证TCP的可靠性与流控特性。
tcp.png
窗口数据的计算过程
TCP缓冲区.png先看发送端:
- LastByteAcked表示收到ACK的最后一个字节,根据TCP的机制,该字节之前的所有字节都是已经被接收并确认过了的。
- LastByteSent表示已经发送但是还未收到ACK的最后一个字节。
- LastByteWritten表示发送方应用进程已经写完的最后一个字节。
接收端:
- LastByteRead表示接收方应用进程已经收到、确认并且读取的最后一个字节。
- NextByteExpected表示接收方期望收到的下一个字节(报文中ack的值)。和LastByteRcvd之间可能有间隔,表示中间还有部分字节没有收到。
- LastByteRcvd表示接收方收到的最后一个字节。
AdvertisedWindow的值就是接收端报文中的Window Size字段的值,MaxRcvBuffer表示接收方的最大缓冲区大小,因此接收方剩余可接收数据的大小为:
发送端在接收到Window Size字段后,结合CongestionWindow(拥塞窗口)制定自身最大的发送窗口:
EffectiveWindow表示发送窗口内剩余可发送的大小:
滑动窗口的工作原理(流量控制)
发送方窗口
TCP发送方滑动窗口.png在TCP会话过程中,发送的字节可以被分为四类:
- 已经被发送并且收到了ACK的字节
- 已经发送但是尚未收到ACK的字节
- 未发送但允许发送的字节
- 未发送且由于发送窗口限制,不允许发送的字节
其中已经发送但是尚未收到ACK的字节和未发送但允许发送的字节,组成了发送端的滑动窗口。
TCP发送端滑动窗口工作过程.png
只有在被连续确认之后,滑动窗口才会移动。例如,如果接收端尚未收到32-35字节,它会一直发送(ACK = 1, ack = 32), 不论是否收到了35以后的字节。一旦接收端收到32-35字节,接收端就会改变ACK报文中ack的值,发送端窗口就可以继续滑动。
接收端窗口
TCP接收端滑动窗口.png字节流在接收端可以被分为3类:
- 已经接收并且已经发送ACK的字节
- 未接收但窗口允许接收的字节
- 未接收且窗口不允许接收的状态
未接收但窗口允许接收的字节就是接收端的滑动窗口大小。只有在收到ack所期望的字节,窗口才会滑动。
滑动窗口基于确认重传机制。
网友评论