上节中说过TCP是面向有连接的协议,具有丢包重发和流量控制的功能,这是他区别与UDP的最大特点。
这节我们就将这两个功能:丢包重发和流量控制。
一、数据包重发
1. 数据发送
- 丢包重发的前提是发送方能够知道接收方是否成功的接收了消息。所以,在TCP协议中接收方会给发送方返回一个通知,也叫做确认应答(ACK),这表示接收方已经接收到了数据包。
根据之前对TCP首部的分析得知,ACK确认应答包中的Ack(确认应答号)应该与发送方下次发送的数据包的序列号(Seq)相等。因此Ack可以理解为:“发送方,下次你从这个位置开始发送,之前的我都收到了。”
- 数据包和应答包都有可能丢失,如果发送方在一段时间内没有收到ACK,就会重发数据:
即使网络正常,由于网络延迟等因素,接收方也有可能收到重复的数据包。因此接收方需要通过TCP首部中的序列号(Seq)来判断这个数据包是否曾经接受过,如果已经接收过,则丢弃这个数据包。
2. 重传超时时间(RTO)
如果发送方等待一段时间以后还没有收到ACK确认应答,就会启动超时重传。这个等待的时间就被称为重传超时时间(RTO,Retransmission Timeout)。
首先,RTO不是固定的,它是动态变化的时候,这个时间总是略大于连接往返时间(Round Trip Time)。这个很好理解:“如果数据发送给对方,再返回回来需要10秒,那我登12秒,超过了12秒,我估计是不会回来了”。
RTT是动态变化的,因为谁也不知道网络下一刻是否拥堵。而当前的RTO需要根据未来的RTT估算获得。RTO不能估算太大,否则会等待过长时间:也不能估算太小,否则会因网速突然变慢,而将不该重传的数据进行重传。
RTO有自己的计算公式,保证即使RTT波动较大,它的变化也不会太剧烈。具体的可以自行查阅相关资料。
3. TCP窗口
按照之前的理论,在数据包发送之后,直至ACK确认之前,发送端都无法再发送数据,这而且包的往返时间越长,网络的利用率和通信性能就越低。
为了解决这个问题,TCP使用了“窗口”这个概念。窗口具有大小,它表示无需等待确认应答就可以继续发送数据包的最大数量。可以理解成接收端所能提供的缓冲区大小。比如窗口大小为4000时,数据发送示意图如下:
- 不等确认就发送连续的数据包会不会有问题呢?
我们最大TCP首部中的确认应答号表示接收方已经收到的数据的最后位置。因此接收方成功接收了1~1000的数据后,会发送一个确认应答号=1001的ACK包。假设1001-2000的数据包丢失了,由于窗口长度比较大,发送方还会继续发送2001-3000数据包,接收端并不会返回这个数据包的确认,因为它最后收到的数据还是1-1000的数据包,所以接收端返回的ACK包的确认应答码还是1001。这表示:发数据的,先别发了,你发的1001字节开始的数据还没来呢。”可以预见到,发送端以后每次发送的数据包的ACK包中的确认应答号都是1001,当连续三次收到确认之后,发送方会知道“这个包的数据对方还没有收到,需要重传”。
因此引入窗口这个概念后,被发送的数据不能立刻丢弃,需要缓存起来以备将来的重发。 - 如果是确认包丢失了呢?
这就是窗口最擅长处理的问题了。假设接收方发送的ACK确认包,第一个确认应答号是1001,第二个确认应答号是4001,那么我们完全相信中间两个包是被成功接收的。因为如果接收方没有接收到数据包,接收方的ACK包中的确认应答号是不会增加的。
这种情况下,如果不使用窗口,发送方就需要重传第二、三个数据包了。因此使用窗口实际上可以理解为“空间换时间”。
二、流量控制
1. 窗口大小
如果窗口过大,会导致接收方的缓存区溢出,这时候数据就会被丢弃了,就会导致无意义的重传。因此,窗口大小是一个可以改变的值,它由接收端主机控制,附加在TCP首部的“窗口大小”字段中。
2. 慢启动
在连接建立的初期,如果窗口比较大,发送方可能会突然发送大量的数据,导致网络瘫痪。因此,在通信的一开始,TCP会通过慢启动算法,得出窗口的大小,对发送数据量进行控制。
慢启动是一种TCP拥塞控制机制。
慢启动算法的基本思想是当TCP开始在一个网络中传输数据或发现数据丢失并开始重发时,首先慢慢的对网路实际容量进行试探,避免由于发送了过量的数据而导致阻塞。
慢启动的过程如下:
- 通信一开始,发送方的拥塞窗口大小设置为1。然后每收到一个ACK应答包,拥塞窗口的数量就翻倍。
- 由于指数增长,很快就会出现应答包超时。此时设置一个慢启动阀值为拥塞窗口的一半,拥塞窗口重新设置为1。
- 继续,每收到一个ACK应打包,拥塞窗口翻倍。直到到达之前设置的阀值,拥塞窗口不在翻倍,而是线性的加1。
- 随着窗口不断增加,可能会收到三次重复确认应答,进入“快速重发阶段”。这时候再将慢启动阀值设置为窗口数的一半,再将拥塞窗口设置为阀值大小。
- 拥塞窗口线性加1增加,直至下次出现三次重复确认应答或超时。
流量控制,是通过发送方和接收方共同控制的。刚刚我们说了接收方会把自己能够承受的最大窗口卸载在TCP首部中的,那么在发送方,也存在流量控制,它叫拥塞窗口。所以TCP协议中的窗口是发送方拥塞窗口和接收端能承受的窗口中的较小值。