传输层--TCP协议(TCP协议详解及可靠性保证)

TCP协议的报头

1.报头:

这里写图片描述

2.各字段解释:
(1)源端口号和目的端口号:

①TCP作为传输层协议,其上一层是应用层,当数据进行向上分用时,需要知道将有效数据交给上一层的谁,所以需要知道源端口号和目的端口号。
②源端口号:表示是哪个服务进程发送的数据
③目的端口号:表示数据要发送给哪个服务进程

(2)32位序号和32位确认序号:

因为TCP是一种可靠的协议,当其传送数据报时,会按照字节进行编号,这些编号就是序号。

  • 当我向你发送数据时,我需要知道你是否收到以及需要知道你收到了哪些数据,通过确认序号就能知道我发送的数据你收到了哪些。又因为我发送的数据需要你确认,你发送的数据报需要我确认,及双方都需要对对方的报文进行确认,所以既需要序号也序号确认序号。
(3)4位首部长度:

因为每一层的报文,都需要知道如何将报头与有效载荷进行分隔,通过首部长度就可以达到该目的。这里的4位首部长度的单位是4字节,也就是:4位能表示的最大数据为15,则报头的最大长度为15*4=60字节。由上面的图可以看到,前5行是基本部分,前5行一共占20个字节,所以TCP报头中4位首部长度默认序列为0101(也就是5),所以TCP报头的长度范围为20~60字节,那么选项部分就最多占40字节。

(4)16位窗口大小:

当我发送数据时,如果不受控制,当我发送的数据超过对方接收缓冲区的大小,那么有些数据包就会被丢弃,但是TCP是可靠协议,为了避免这种问题,所以发送数据时需要知道对方的接收能力,根据对方的接收能力来合适的发送数据,就能为TCP的可靠性提供一个保证。这里的窗口大小就表示的是自己的接收能力(也就是自己剩余缓冲区的大小)。

  • 注意:这里的窗口大小是自己接收缓冲区剩余窗口的大小,而不是对方的,因为这个数据报是要发给对方的,对方自己知道自己剩余缓冲区的大小,但是对方不知道我剩余缓冲区的大小,所以这里的窗口大小是我剩余缓冲区的大小。
(5)16位校验和:

校验数据是否正确

(6)16位紧急指针:

因为有时候有的数据需要优先被上层处理,但是报文又是按照顺序放在接收缓冲区里,不能破坏顺序,所以紧急指针就可以标识哪部分是紧急数据。

(7)6位保留位:

现在不用以后有可能会用到,所以现在可以保留下来,作为保留位。

(8)选项:

有时候再选项里面填充报文的一些补充信息。

(9)在第四行中,还有6个非常重要的比特位(标志位),下面着重来讲这些位。
3. 6位标志位:

(1)URG:紧急指针标志位
(2)ACK:对报文的确认标志位
(3)PSH:当一方收到携带该标志位的报文时,发送端提示接收端上层的应用层服务赶紧将接收缓冲区的数据读出去,否则接收缓冲区就放不下数据了。
(4)RST:请求重新建立连接,当报文中该标志位被置为1就表示以前建立的连接都无效需要重新建立连接,那么需要断开以前建立的连接,请求重新建立连接。

  • 为什么会有RST?
    例1:在电脑上网过程中,如果电脑异常关机之后,连接就无效了,当客户端主机再重新启动时会向服务器请求重新建立连接,那么服务器就要断开以前的连接再重新建立新的连接。
    例2:我们可以发现QQ如果长时间不在线就会让图案颜色变淡,但是当我们再次点击的时候就会重新登录。
    上面例子可以说明:当连接建立之后,保持连接的时间是有限的,当超过这个时间之后,服务器会发送一个试探报文,多次发送一直没收到客户端的相应就会断开相应的连接,因为服务器保持连接就要占据相应的资源,操作系统还要对其进行维护,如果客户端没有使用就可以断开相应的连接,当需要使用的时候再重新建立连接。

(5)SYN:请求建立连接,用于三次握手中
(6)FIN:请求断开连接标志位,用于四次挥手中

注意:TCP不仅有发送缓冲区还有接收缓冲区

TCP协议的特点

1.有连接
2.可靠
3.面向字节流

TCP是如何保证可靠性

1.连接管理机制

三次握手和四次挥手,这个主题下一个博客单独来讲解。

2.确认应答机制,序号和确认序号

(1)TCP会将需要发送的数据按照字节进行编号,这个编号就叫做序号(序列号);
(2)当客户端向服务器发送数据,数据会进行编号,如果客户端一次发送的数据的编号是1~1000,若服务器收到客户端发送的数据就会向客户端发送一个确认报文,里面携带一个确认序号是1001,表示1001之前的报文我(服务器)已经收到,下次客户端发送的数据序号就从1001开始;
(3)这个服务器对客户端的确认报文里面就将ACK标志位置为1,并且该报文里还携带相应的确认序号,这个确认序号就表明当前我已经收到你发送的哪些数据,下一次你应该从哪里重新发。

3.超时重传
  • 先来解释下什么叫做丢包问题?
    数据包在传输过程中,无法正确从一端传到另一端,或者接收端没有收到发送端发来的数据,此时就说明该数据包丢了,出现的这种问题就叫做丢包问题。

(1)当客户端向服务器发送数据时,有可能数据在传输过程中,数据包丢了,那么服务器就无法接收到数据,那么服务器就不会给出相应的确认报文,那么当超过一段时间后,发送端发现还没有收到服务器发来的ACK,客户端就会重新发送数据包。
(2)还有一种情况是,服务器收到客户端发来的数据包,服务器也发送了相应的ACK报文,但是ACK报文在传输的过程中丢了,此时也产生了丢包问题,同样超过一段时间后,客户端会重新发送相应的数据包是,此时服务器就会收到两个同样的数据包,但是由于TCP报头里面含有序号,就会对相同的数据包进行去重。这样就保证了数据包能够正确被对方收到,也就保证了可靠性。
(3)超时的时间如何确定?
超时的时间不能太长也不能太短,太长就会使得效率变慢,等待时间边长;时间太短就会容易出现接收端多次收到重复的包。
操作系统会动态计算这个时间,一般是500ms,当超过500ms还没有收到对方的确认报文,那么就会进行重发,如果重发后还没有收到确认报文,再过2倍的500ms进行重发,每首到然后4倍的500ms时间进行重发,当发送超过一定数量限定的时候,就不再重发,TCP会认为网络出现问题或者连接异常,就会断开连接。
(4)超时重传的数据包是从哪里来的?
因为TCP有发送缓冲区,里面存放着发送数据的拷贝,当需要重发时就可以从发送缓冲区里取数据进行重发。

4.流量控制

(1)什么是流量控制?
我们知道:在TCP报头里面有一个字段叫做16位的窗口大小,这个窗口大小表示的是对方的接收能力,发送端根据接收端的接收能力来控制自己的发送速度,这个就叫做流量控制。
(2)为什么需要流量控制?
如果发送端不对发送速度进行控制,如果一次发的太快,就会使得接收端缓冲区很快满甚至有可能让对方接收缓冲区的数据溢出从而会导致数据包被丢,但是这种情况下不会重发,就导致发送端发送的数据接收端有的没有接收到,就无法保证TCP的可靠性,因此需要流量控制。

5.拥塞控制

(1)什么是拥塞控制?
网络中一些链路或者路由器的缓存或者处理能力是有限的,当网络的需求大于他们的处理能力,就会出现网络拥塞问题。因此需要对传入到网络上的数据的数量加以控制,这就叫拥塞控制。
(2)为什么需要有拥塞控制?
网络有时候会出现拥堵问题,如果在网上传输数据速度不加以控制就会导致网络越来越拥堵,不仅使得数据无法正确传输到目的地,并且导致本来已经拥堵的网络变得更加瘫痪,网络问题会越来越严重,因此需要拥塞控制。
(3)TCP如何进行拥塞控制?
由上面可以知道TCP中有三个窗口,分别是滑动窗口、拥塞窗口和TCP报头里面的窗口。

  • 滑动窗口表示的是无需等待对方ACK应答能够发送数据的最大值;
  • 拥塞窗口表示的是网络的接收能力;
  • TCP报头里面的窗口大小表示对方的接受能力(对方接收缓冲区的剩余大小);

因此TCP的拥塞控制就是控制自己的发送能力,每次发送数据选取拥塞窗口和接收方反馈回来的窗口中的较小值作为自己的发送的能力(即发送数据时,滑动窗口是拥塞窗口和窗口的较小值),另一方面我们可以从接收端反馈回来的报文里面知道接收端的窗口大小,但是不知道拥塞窗口大小,因此确定一个合适的拥塞窗口变得至关重要。
(4)如何确定拥塞窗口的大小?

  • 采用慢启动和拥塞避免算法。

①慢启动:刚开始时定义拥塞窗口的大小为1,每收到一个ACK,拥塞窗口的值加1直到拥塞窗口的值等于慢启动的阈值就不再按照这种方式。但是这种形状像指数的形式,我们会想指数增长不是很快么,为什么叫做慢启动,因为慢启动只是表示初始很慢。
②当拥塞窗口的数量达到慢启动的阈值之后,此时用到拥塞避免算法,采用线性增长的方式,也就是加法增大,一直增长到使得网络出现拥塞的便不再增长;
③当网络出现拥塞之后,又采用拥塞避免算法的“乘法减小”将拥塞窗口的值变为1,将新的慢启动的阈值变为上一次的一半,然后重复上面的过程。
这里写图片描述

注意:少量的丢包采用超时重传,当出现大量的丢包就应该是网络出现了问题,就应该采用拥塞避免算法。
  • 我们知道UDP可以提高效率,那么TCP在做了这么多保证可靠性的条件下,效率是否就会低下?
    不会,TCP在保证可靠性的前提下,还做了一些措施来提高效率。

TCP如何提高效率

1.滑动窗口

(1)滑动窗口表示的是:无需等待对方应答而发送数据的最大值。
(2)滑动窗口如何能够提高效率?

  • 如果发送一个数据包然后等待一个ACK,等待之后再继续发然后继续等,就会使得效率比较低,只要有一种方法能够批量的发然后批量的等,使得等待的时间能够重叠起来,就能够提升效率,滑动窗口就能达到这样的目的。
  • 滑动窗口的大小是受对手的接收能力和网络拥塞窗口控制的,在其控制下可以选取一个最大值,一次发送这么多的数据包,当我们收到一个ACK之后,再将滑动窗口进行滑动。

(3)采用滑动窗口如果出现丢包问题如何处理?

  • 我们知道丢包问题分为两种,一种是数据包丢了,一种是ACK丢了。
  • 例如我们一次发送数据包为1-1000、1001-2000、2001-3000、3001-4000
    如果数据包1000-2000丢了,那么就会一直收到对方的确认报文,告诉我们下一个是1001,当我们多次收到对方确认报文里面向接收方索要1001,那么发送端就可以知道1001-2000报文丢了,就可以很快的进行重传(这就叫快重传),那么下次收到对方的ACK报文里确认序号就直接是4001(表示4000以前的数据包我都已经收到了)。
  • 如果ACK丢了,但是会收到对方对后面报文的确认,例如1001-2000的报文丢了,但是收到了一个4001的确认报文(表示4000之前的报文已经收到),里面涵盖了对之前报文的确认,也就不用重发,这样就能减小重发的次数,就能够提升效率。
2.延迟应答

(1)如果发送端发送一个数据包之后接收端立即返回一个ACK,此时接收端返回的窗口大小可能比较小,因为接收端接收缓冲区的数据还没有被上层处理。但是如果接收端等待一段时间,有可能上层就把数据从接收缓冲区里面读走了,那么此时接收端再返回一个ACK报文里面窗口就比直接返回的窗口要大。
(2)窗口越大,吞吐量就越高,吞吐量越高效率也就越高。
(3)但是要注意不是所有的报文都能够延迟应答,要隔一段时间就必须立即应答一次或者隔一些包就应该应答一次。

3.快重传

(1)上面滑动窗口里面丢包问题的第一种情况 :例如我们一次发送数据包为1-1000、1001-2000、2001-3000、3001-4000,如果数据包1000-2000丢了,那么就会一直收到对方的确认报文,告诉我们下一个是1001,当我们多次收到对方确认报文里面向接收方索要1001,那么发送端就可以知道1001-2000报文丢了,就可以很快的进行重传(这就叫快重传),快重传也叫告诉重发控制。
(2)我们可以看到快重传效率比较高,那么有了快重传之后为什么还要超时重传?
虽然快重传效率比较高,但是快重传需要收到多次对以前报文的重复确认才会重传,但是如果数据包较少,有可能都不会收到多次重复确认,就不会重传,但是超时重传超过一定时间还没有收到ACK一定会重传。

4.捎带应答

(1)当发送方给接收方发送数据包时,接收方会给发送方发送一个ACK报文,有时候接收方也会给发送方发送一些数据包,此时我们的ACK就可以乘着接收方发送的数据包回来,这样就将两次发送数据包只用一次发送就可以,这样就可以提升效率。
(2)可以发现捎带应答是建立在延迟应答的基础上的,因为没有延迟应答那么ACK就要立即被返回。

猜你喜欢

转载自blog.csdn.net/xu1105775448/article/details/80928967