TCP协议 报头格式+十个核心机制详解 (画图超超超详解 一篇看懂!!!)

目录

TCP协议段格式

一、确认应答

        确认应答工作原理:

二、超时重传        

        丢包分为两种情况: 

        超时重传工作原理:

        去重操作:

        确定超时时间:

三、连接管理

1、三次握手

三次握手工作原理:

三次握手的意义:

两次握手/四次握手行吗?

2、四次挥手

四次挥手工作原理:

四次挥手可以合并为三次吗?

3、TCP状态

三次握手+四次挥手流程图:

·TIME_WITE

·CLOSE_WITE

四、滑动窗口+快速重传

滑动窗口工作原理:

滑动过程:

丢包情况处理:

1、数据包已到达,ACK丢失

2、数据包丢失

五、流量控制

流量控制工作原理:

六、拥塞控制

七、延时应答

延时应答的限制:

延时应答工作原理:

八、捎带应答

捎带应答工作原理:

九、粘包问题

十、异常情况

1、进程终止

2、机器重启

3、机器掉电/网线断开


        TCP全称为“传输控制协议(Transmission Control Protocol)”,对数据的传输进行一个详细的控制。

TCP协议段格式

·源/目的 端口号:表示数据从哪个进程来,到哪个进程去。

·32位 序号/确认号:用来跟踪该端发送的数据量

·4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少4个字节),所以TCP头部最大长度是 15*4=60。

·6位标志位:

        URG:紧急指针是否有效

        ACK:确认号是否有效

        PSH:提示接收端应用程序即将从TCP缓冲区把数据读走

        RST:对方要求重新建立连接,我们将携带RST标识的报文段称为复位报文段

        SYN:请求建立连接,我们把携带SYN标识的报文段称为同步报文段

        FIN:通知对方,本端要关闭了,我们称携带FIN的报文段称为结束报文段

·16位窗口大小:存放窗口大小信息

·16位校验和:发送端填充,CRC校验。接收端校验不通过则说明数据有问题。此处的校验和不关包含TCP首部,也包含TCP数据部分。

·16位紧急指针:标识哪部分数据是紧急数据。

·40字节头部选项:包含一个窗口扩大因子M,实际窗口大小为 窗口字段的值左移M位


一、确认应答

        确认应答是保证TCP可靠性通信最核心的机制之一。可靠性指的并不是数据百分百到达对方,而是尽可能的传输过去。所以在这个过程中,一个重要前提就是知道数据是否成功传输过去了。

确认应答工作原理:

        TCP将每个字节的数据都进行了编号,即为序列号。每个ACK都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据,下一次你要从哪里开始发

二、超时重传

        超时重传是针对确认应答的重要补充。针对确认应答过程中或数据发送过程中的丢包情况进行处理的机制。

        丢包是客观存在且不可预期的,因为在网络上的通信设备转发能力存在上限,当转发的数据量超过上限时,救会出现 “丢包”

丢包分为两种情况:

1、数据丢失:当 主机A 发送数据给 主机B 之后,可能因为网络拥堵等原因,数据无法到达主机B

2、ACK丢失: 主机B 收到了 主机A 发来的数据,但返回的确认应答ACK可能因为网络拥堵等原因,无法到达主机B

如果主机A 在一个特点时间间隔内没有收到主机B发来的确认应答,就会进行重发。

超时重传工作原理:

去重操作:

        在ACK丢失的情况下,主机A会发送重复数据,主机B会收到很多重复数据。那么TCP协议需要能识别出哪些是重复的包,并把重复的丢弃掉。这时候我们就可以利用前面提到的序列号,从而达到去重的效果。

        在接收方有一个数据结构:接受缓冲区。当有数据到达接收方,数据就会进入接收缓冲区。当应用程序对数据进行读取,数据就会从缓冲区删除。为了确保读取到的数据不会重复,会根据数据的序号对缓冲区里的数据进行去重。

确定超时时间:

        在理想的情况下,找到一个最小的时间,保证 “确认应答一定能在这个时间内返回”。但这个时间的长短,随着网络环境的不同,是有差异的。如果超时的时间太长,会影响整体的重传效率;如果超时时间设的太短,有可能会频繁的发送重复的包

        TCP为了保证无论在任何环境下都能比较高性能的通信,因此会动态计算这个最大超时时间。在超时重传时,重传频率会逐渐降低。累计到一定次数后,TCP认为网络或者对端主机出现异常,会强制关闭连接

Linux中,超时以500ms为一个单位进行控制,每次判定超时重发的时间都是500ms的整数倍。如果重发一次后仍然得不到回应,等待2*500ms后再进行重传。如果仍然得不到回应,等待4*500ms后再进行重传。如果还是得不到回应,以此类推,以指数形式递增。

TCP中可靠连接的核心是:确认应答+超时重传

三、连接管理

在正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接。

1、三次握手

        三次握手由客户端发起,三次握手建立连接是在传输业务数据之前,握手好了才能进行后续业务的传输~

三次握手工作原理:

三次握手的意义:

1、投石问路,确认当前通信路径是否通畅

2、协商参数,通信双方共同确认一些通信中的必备参数数值

        比如TCP通信时使用的序号。序号往往不是从 0/1 开始的,而是三次握手协商出的一个序号。一般前后两次连接的起始序号相差会很大。为了避免上一次连接发出的序号在下一次连接中被接受,避免 “前朝的剑斩本朝的官”~

两次握手/四次握手行吗?

·两次握手不可行!

        因为此时服务器对于 “接受能力” 和 “发送能力” 的认知是不完全的,根据原理图我们也可以看出,如果只有两次握手,客户端可以明确自身的 “接受能力” 和 “发送能力”是完善的,但服务器端只能确定自己可以收到客户端发送的数据,无法确定客户端能否收到自己发出的数据。

·四次握手可行,但没必要!

        四次握手可行,但没必要,会降低效率。

2、四次挥手

        四次挥手可以是客户端发起,也可以是服务器端发起。“断开连接”就是通信双方把之前保存的对端信息删除,TCP中希望达成的结果就是双方“互删”。

四次挥手工作原理:

四次挥手可以合并为三次吗?

        如能。

        在三次握手中,SYN 与 ACK 都是内核自动发送的,发送时间是同一时机,所以在三次握手中可以合并。在四次挥手中,FIN 和 ACK 的发送不一定是同一时间,ACK是收到FIN后就立即返回,是由系统内核控制的;FIN是在应用程序中调用close时才会触发。

        所以一般情况下不能合并,但当存在 延时应答机制 时,可以合并。

3、TCP状态

三次握手+四次挥手流程图:

值得关注的是四次挥手过程中的两个状态,一个是TIME_WITE,一个是CLOSE_WITE。

·TIME_WITE

        TIME_WITE的存在是为了避免连接双方一边断开了,一边没断开的情况,用于应对重传FIN

        如果服务器端出现了大量 TIME_WITE状态,说明服务器触发了大量主动断开TCP操作,这并不科学,因为一般情况下都应该是客户端提出断开连接。

·CLOSE_WITE

        CLOSE_WITE状态是为了等待应用程序调用 close方法。

        一般而言,如果服务器上出现了大量的  CLOSE_WITE状态,说明服务器没有正确的关闭 socket,导致四次挥手没有正确完成。此时加上对应的 close即可解决问题~

四、滑动窗口+快速重传

        滑动窗口是一种提高传输效率的机制。确认应答机制对于每一个发送的数据段,都要给一个 ACK 确认应答,收到 ACK 后再发送下一个数据段。这样做有一个较大的缺点,就是性能比较差,尤其是数据往返时间较长的时候。

        既然像那样一收一发的方式性能较低,那么我们可以一次发送多条数据,就可以大大的提高性能。(将多个数据段的等待时间重叠到一起,节省时间)

滑动窗口工作原理:

        滑动窗口的窗口大小指的是无需等待确认应答而可以继续发送数据的最大值,上图的窗口就是4000个字节(四个段)。

·发送前四个段的时候,不需要等待ACK,直接发送

·收到第一个ACK后,滑动窗口向右移动,继续发送第五个段的数据,以此类推…

·操作系统内核为了维护滑动窗口,需要开辟 发送缓冲区 来记录当前还有哪些数据没有应       答。只有确认应答过的数据才能从缓冲区删除。

·窗口越大,则网络的吞吐量就越高

滑动过程:

丢包情况处理:

        提高效率的前提是保证可靠性,所以TCP也有一系列机制来保证滑动窗口过程中的可靠性。

丢包分为两种情况:

1、数据包已到达,ACK丢失

2、数据包丢失

1、数据包已到达,ACK丢失

        这种情况不需要进行处理。ACK确认序号的规则,巧妙的解决了ACK丢失的问题。这种情况下ACK丢了不要紧,因为可以通过后续的ACK进行确认前面的数据已经收到了。

        假设返回2001的ACK丢失了,主机B也可以通过收到的3001确认应答来知道0-3000的数据都发过来了,所以0-2000的数据肯定也已经发过来了。

2、数据包丢失

        当数据包丢失的情况,就需要我们对他进行处理。这边会借助 “超时重传” 这样的机制来解决问题。

        当某一段报文段丢失之后,发送端会一直收到1001这样的ACK,就像是在提醒发送端 “我要的是1001的数据”。如果发送端主机连续三次收到了同一个 “1001” 这样的应答,就会将对应的1001-2000数据重新发送。

        这个时候收到了1001之后,再次返回的ACK就是7001了,因为2001-7000接收端其实已经收到了,被放到了接收端的接收缓冲区中。

        就像拼图丢失了一块,只要把原本确实的那一块拼上,就可以正常传输数据了。

        对于数据丢失,只要把缺失的数据重传即可,其他的数据不必重传。一旦缺口补上,接下来就可以从队列最后一个数据的序号继续往后索要。

这种机制也被称为“高速重发控制”(也叫“快重传”),快速重传是超时重传的一种特殊形式。

五、流量控制

        接收端处理数据的速度是有限的,如果发送端发送的太快,导致接收端的缓冲区满了,这个时候如果继续发送数据,就会造成 丢包,继而引起一系列连锁反应~

        因此TCP支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做——流量控制

·接收端将自己可以接收的缓冲区大小放到 TCP 首部的 “窗口大小” 字段,通过ACK端通知发    送端

·窗口越大,说明网络吞吐量越高

·接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置为一个更小的值发送给发送端

·发送端收到这个窗口之后,就会减慢自己的发生速度

·如果接收端缓冲区满了,就会将窗口设置为 0,这时发送端无法再发送数据。但发送端会定   期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端,当窗口大小不为0则可以继   续发送

        以上过程很类似 “蓄水池问题”,池子一端出水,一端进水,通过出水的速度来调整进水的速度,其目的就是为了水不溢出,也就是网络中对应的 不丢包

流量控制工作原理:

        接收端通过TCP首部的 “16位窗口字段”来通知窗口大小,在“16位窗口字段”中存放了窗口大小信息。

        16位数字最大可表示65535,但并不代表TCP窗口最大是65535。

        实际上,TCP首部40字节选项中还包含了一个 窗口扩大因子M,实际窗口大小是 窗口字段的值左移M位。

六、拥塞控制

        拥塞指的是网络中间链路出现丢包的情况,一次性传输太多的数据就会造成拥塞。

        虽然TCP有了滑动窗口这个“大杀器”,能够高效可靠的发送大量数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。因为网络上有很多计算机,可能当前的网络状态就比较拥堵,如果这个时候发送大量数据,可能会让本就拥堵的网络状态雪上加霜,造成丢包

        TCP引入了 慢启动 机制,先发少量的数据,探探路,摸清当前的网络状态,再决定按多大的速度传输数据

        发送开始的时候,设置拥塞窗口的大小为 1 ,每收到一个ACK应答,拥塞窗口大小 +1。每次发送数据包的时候,将拥塞窗口和接收端主机反馈的窗口大小对比,取较小的值作为实际发送的窗口。拥塞窗口的增长速度是指数级的,虽然启动速度慢,但是增长很快

        为了数据的正确性,我们不能让窗口增长的那么快,所以此处引入一个慢启动的阈值。当拥塞窗口超过这个阈值时,不再按照指数方式增长,而是按照线性方式增长。当TCP开始启动的时候,慢启动阈值等于窗口最大值;在每次超时重传的时候,慢启动阈值变为原来的一半,同时拥塞窗口置回1。

        少量的丢包,我们仅仅是触发超时重传;大量的丢包,我们就认为此时网络拥塞。当TCP通信开始后,网络吞吐量(窗口)会逐渐上升;随着网络发送拥堵,吞吐量会立即下降。

        拥塞控制归根结底就是 TCP协议 想尽可能快的把数据传输给对方,但是又要避免速度太快给网络造成太大压力的折中方案。

七、延时应答

        核心目的:提升传输的效率。

        决定传输速度最关键的因素是窗口大小,在能承受的前提下,尽可能的提高窗口大小可以提高速度。通过延时应答机制可以尽可能的提高窗口大小。

        如果接收数据的主机在收到数据后立刻返回ACK应答,这时候返回的窗口可能较小。 

        假如接收端缓冲区大小为 1M。收到了 500K 的数据,如果此时立即应答,返回的窗口大小就是 500K;但实际上处理端处理的速度可能很快,10ms之内就把500K的数据从缓冲区消费掉了。

        在这种情况下,接收端处理能力还远远没有到达自己的极限,即使窗口再大一点,也能处理。如果接收端稍微等待一会再应答,那么这个时候返回的窗口大小就会更大。窗口越大,网络的吞吐量越大,传输效率越高。

        所以我们的目标就是在保证网络不拥塞的情况下,尽可能的提高传输效率。

延时应答的限制:

并不是所有的包都可以延时应答,延时应答也是有限制的~

1、数量限制:每隔N个包就应答一次

2、时间限制:超过最大延迟时间就应答一次

延时应答工作原理:

八、捎带应答

        捎带应答是建立在延时应答的基础上,提高效率的机制。

        我们发现很多情况下,客户端服务器在应用层也是 “一发一收”的,意味着客户端给服务器 say “Hi~”,服务器也会给客户端回一个 “Hi~”。那么这个时候 ACK 就可以搭上顺风车,和服务器回复的 “Hi~” 一起回给客户端。

捎带应答工作原理:

        正常来说,ACK是内核收到后自动回复的;响应数据是执行一系列逻辑后返回的。由于延时应答的存在,ACK不一定立即返回,可以让ACK稍等一会,等待响应数据一起返回,这样可以通过把两次传输合并在一起,提高效率~

九、粘包问题

        这边 “粘包” 中的 “包” 指的是 应用层的数据包。

        在TCP的协议头中没有像UDP一样的 “报文长度” 这样的字段,但是有一个序号这样的字段。站在传输层的角度,TCP是一个一个报文传输过来,按照序号排好序放在缓冲区中。站在应用层的角度,看到的只是一串连续的字节数据。应用程序无法判断从哪里到哪里是一个完整的数据包。这就是 “粘包”。

        那么如何避免 “粘包问题”呢?归根结底就一点:明确两个包之间的边界

·对于定长的包,保证每次都按固定大小读取即可

·对于变长的包,可以在包头的位置,约定一个包总长度的字段,从而就知道了包的结束位置

·对于变长的包,还可以在包和包之间使用明确的分隔符(分隔符不能和正文冲突)

十、异常情况

1、进程终止

        进程终止会释放文件描述符,仍然可以发送FIN,所以和正常关闭没什么区别。在这种情况下可以完成四次挥手。

2、机器重启

        机器重启和进程终止的情况相同,但不一定能挥完四次挥手,没挥完也可以成功断开。

3、机器掉电/网线断开

        这种情况接收端无法得知连接断开,会认为连接还在。一旦接收端有写入操作,接收端发现连接不在了,就会自己断开。即使没有写入操作,接收端中也有一个保活定时器,会定期询问对方是否还在,如果发现对方不在了,也会把连接断开。


          以上就是 TCP协议 报头格式+十个核心机制详解 (画图超超超详解 一篇看懂!!!)  的全部内容了,希望能对您有所帮助!

  • 34
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值