本文要点
- TCP的特点
- TCP的可靠传输是如何实现的
- TCP数据报
- TCP内部的四种计时器
什么是TCP?
TCP是一种面向链接的,可靠的,面向字节流的运输层通信协议,它负责将IP层传送上来的数据报交给对应的应用程序,以及将应用程序传送下来的数据报进行管理以后传递给IP层。今天我们就来谈一谈运输层的TCP协议。
TCP数据报
上图给出了IPC数据报首部的相关字段,以及各字段的解释。
TCP的特点
1.面向连接的运输层协议,在使用TCP协议之前,必须要先建立连接,在传送完数据后,必须要释放连接。
2.每一条TCP连接只能有两个端点。
3.TCP是提供可靠支付的服务。
4.TCP提供全双工通信,即允许通信双方在任何时候都能够发送数据,并且在连接的两端都设有发送缓存和接收缓存,用来存放双向通信的数据。
5.面向字节流:”流“指的是流入到进程或从进程中流出的字节序列;TCP把应用程序交下来的数据看成是一连串的无结构的字节流;另外,TCP对应用进程一次把多长的报文发送到TCP的缓存中是不关心的,TCP根据对方给出的窗口值和当前网络阻塞的程度来决定一个报文段应该包含多少个字节。
TCP是如何做到可靠传输的?
流量控制
流量:指的是点对点的通信量。
什么是流量控制?:流量控制就是让发送速率不要过快,让接收方可以来得及接收。
滑动窗口:在TCP中,通过TCP报文段中的窗口大小字段来对流量进行控制,规定发送方的发送窗口不可大于接收方发回的窗口大小。
下面我们就来简单的谈一谈TCP的滑动窗口的机制:
前面我们提到,在TCP的面向字节流的传输中,在发送方和接收方都有一块缓冲区;在发送方,应用程序只需要将数据写到发送缓冲区中,剩下的传输工程就交给TCP的滑动窗口来解决了;同理,在接收方,滑动窗口将数据写到接收缓冲区中,接收方的应用程序只需要读就可以了。
发送方的滑动窗口:
接收方的滑动窗口:
在接收端,只能按顺序对收到的数据中的最高序号给出确认序号(ACK),如果接收应用程序能及时从接收缓存中读取数据,那么接收窗口就会增大。
如果数据不按顺序到达,那么TCP对不按顺序到达的数据是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,在按照顺序交付给上层的应用程序。
发送端如果没有收到接收端的确认序号,那么就会把没有被确认的数据暂时保留,这样做便于超时重传时再使用。
拥塞控制
什么是拥塞?
网络拥塞现象发生在对网络中的某一资源的需求超过了该资源所能提供的可用部分,这时便会发生拥塞现象,拥塞会导致网络的性能下降。
什么是拥塞控制?
所谓的拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或者链路不至于过载。
如何进行拥塞控制?
首先我们要提到下面的算法和原则:
* 拥塞避免算法:发送方维持一个拥塞窗口*的状态变量,拥塞窗口的大小取决于网络的拥塞程度,并且在动态的变化,发送方让自己的窗口等于拥塞窗口。
发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就再增大一些,只要网络出现拥塞,那么拥塞窗口就减少一些。
慢开始门限(ssthresh):这个状态变量是为了配合拥塞窗口(cwnd)使用的,当cwnd<ssthresh,使用慢开始算法,当cwnd=ssthresh,既可以使用拥塞控制,也可以使用拥塞避免。当cwnd>ssthresh,停止使用慢开始算法,改用拥塞控制算法。
慢开始算法:当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么就有可能引起网络拥塞,所以我们先探测一下,由小到大的增加拥塞窗口(cwnd);只要发送方判断网络出现拥塞(根据有没有收到确认),就要把慢开始门限sstresh设置为出现拥塞时的发送方窗口的一半,并把cwnd设置为1.
那么我们怎么探测发生了网络拥塞呢?如果发送方设置的超时计时器时限已经到了,但还是没有收到确认,那么很可能是网路出现了拥塞。
除了上面的慢开始和拥塞控制算法,后面有衍生除了另外两种算法:
快重传算法:首先要求接收方没收到一个失序的报文段后就立即发出重复确认,如果发送方重复收到了几次接收方的确认,那么便会重传接收方没有收到的字段。
快恢复算法:是与快重传配合使用的算法,当发送方连续收到多个重复确认时,就执行“乘法减小算法”,把慢开始门限减半;接着把拥塞窗口(cwnd)设置为慢开始门限减半之后的数值,然后开始执行拥塞避免算法。
下面我们根据一副图片来体会下两种控制方法:
TCP中的四种计时器
此外,为了实现更可靠的数据传输,TCP内部还实现了四种计时器:
1.重传计时器
创建:当TCP发送报文段时,就会创建该特定报文段的重传计时器。
创建了该计时器后,可能会有两种情况发生:
1、若在计时器截止时间之前收到了对方发送的报文段的确认,则撤销该计时器。
2、若在截止时间之后,没有收到对方发送过来的特定报文段,则重传报文段,并将此计时器复位。
2.坚持(持续)计时器:为了应对0窗口大小通知
若接收TCP宣布了窗口大小为0,发送TCP就会停止传送此报文段,直到接收TCP发送确认并宣布一个非零的窗口大小,但接收TCP发送的这个确认可能会丢失,在TCP中对确认是不需要再发送确认的,若确认丢失了接收TCP并不知道,它会认为确认已经成功发送了。 但实际情况是发送方没有收到接收方的TCP报文,它会一直等待接收方发送确认报文,这样就会造成双方都在等待,于是句造成了死锁问题。
为了打开死锁,在每个链接中都会有一个坚持计时器,当发送方收到一个窗口大小为0的确认时,就会启动坚持计时器。当坚持计时器超过期限时,发送方就会发送一个特殊的报文(探测报文段)。这个报文段只有一个字节的数据,只有一个序号,它的序号不需要确认,探测报文会题型对方,确认它发送的窗口不为0的字段已经丢失,必须要采取重传措施。
3.保活计时器
保活计时器是用来防止两个TCP之间的连接出现长时期的空闲。每当某一端收到了对方发来的信息时,就将保活计时器复位,保活计时器通常设置为两个小时,若两个小时后这条连接的两端没有发送信息,它就让设置了保活计时器的端口发送一个探测报文段,若连续发送了10个探测报文段(75s一个)还没有相应,就认为那一段出现了故障,并终止和那端的连接。
4.时间等待计时器(超时时间=2MSL)
该计时器是在连接终止期间使用的,在第三次挥手中,客户端收到服务段发送的FIN报文后,客户端就会启动时间等待计时器,时间设置为2MSL,并发送最后一个ACK;这个ACK有下面两个作用:
(1)、保证2MSL时间内,服务端能够收到最后一个ACK;
(2)、能够保证之前某些在网络中滞留很久的发给服务器的报文不会再本次链接关闭后再到达服务器。
在最后的两次挥手期间启动了两种计时器,分别是服务端向客户端发送FIN后启动了超时重传计时器;以及客户端收到FIN后,向服务端发送ACK,并启动了时间等待计时器。