文章目录
文章内容概览
TCP协议的流量控制
流量控制是TCP协议特有的功能,对于UDP或者其它的一些协议,是没有流量控制
流量控制,简单的来说就是,接收方希望发送方将数据发送的慢一些。一般来说,我们是希望越快越好,但是,还是需要考虑一些实际的情况。比如接收方不能那么快的去接收很大的流量,所以希望发送方的流量慢一些。这就是流量控制
- 流量控制指让发送方发送速率不要太快
- 流量控制是使用滑动窗口来实现的
在TCP首部中有窗口这个字段,它占16个比特位,用来指明允许对方发送的数据量。在可靠传输的基本原理这篇文章中有结合确认号和窗口进行了一个运算。比如说,假设确认号是501,窗口大小是1000,就表示说,发送方可以发送501~1500这个范围的1000个字节的数据,这个就是窗口所起到的作用。那滑动窗口是怎么做到流量控制的?
假设现在有一个发送方计算机和一个接收方计算机,从上往下是它们之间交互的时间轴
- 假设发送方发送了一个序列号为1的数据,发送数据的大小是100个字节
- 发送方还可以进行第二次发送,此时发送的数据的序列号就应该是101,也假设发送数据的大小是100字节
- 此时接收方已经接收到了200个字节的数据,假设此时接收方发送了一个确认消息,确认号是201,201表示的就是期待接收到的下一个字节的序号,并且发送的确认消息中还有一个窗口的大小,假设是300,表示告知发送方还可以发送300个字节的数据。确认消息中的ACK标记为1
- 发送方在知道了窗口大小为300之后,它就可以继续发送300个字节的数据。首先它可能就会发送序列号为201的100个字节的数据,此时发送方还能再发200个字节的数据
- 假设此时发送方发送了序列号为301的200个字节的数据,此时接收方就可以进行确认了,确认说,它已经接收到了601序列号之前的所有数据了,此时窗口大小为0,也就是说发送方不能再进行数据发送了
以上就是通过窗口大小控制对方发送速率
假如接收方发送了窗口为0的消息之后,它马上对接收到的数据进行处理,处理之后交给应用层,一段时间之后,接收方就又可以接收信息的消息了。此时,接收方就会向发送方发送一个消息,告诉它说,当前我的窗口是1000,也就是可以接收1000个字节的数据。发送方在收到这个消息之后,发送方又会进行数据的封装,并且将数据发送给接收方。这个就是接收方通过调整窗口的大小来告知发送方可以继续的发送数据
考虑一个特殊情况
假设接收方在通知发送方,它的窗口为1000的消息在传输过程中丢失了。这种情况会导致什么样的后果?
对于发送方:发送方会一直等待,因为它还是以为接收方的窗口为0,所以它一直等待接收方的窗口调大
对于接收方:接收方已经将窗口调大的消息告诉发送方了,理论上,发送方在收到消息之后,会将信息的消息发送给接收方。因此,接收方也会一直等待
所以,因为窗口数据报文的丢失,导致发送方和接收方都会一直的在等待,形成死锁的局面。此时可能就会有疑问,TCP不是可靠传输的吗?这个消息为什么会丢失呢?
其实在讨论TCP的可靠传输时,主要是从数据的角度去考虑的。也就是说,对于TCP的可靠传输,都是对数据的确认。比如序列号、以及确认号都是对数据的字节进行确认的,对于特殊的消息,比如窗口的大小,其实是没有超时重传机制的。因此就会出现上边提到的死锁局面
坚持定时器
要处理上边出现的死锁情况,就需要TCP中的第二个定时器,坚持定时器
- 当发送方接收到窗口为0的消息,则启动坚持定时器
- 坚持定时器每隔一段时间发送一个窗口探测报文(用来询问窗口有没有增大,这样就可以解决因发送窗口大小的消息丢失导致的死锁局面)