【网络原理篇2】TCP报头详解

       在这一篇文章当中,了解到TCP是属于传输层的协议;当数据从应用层向传输层发送的时候,如果使用的是TCP协议,那么就需要把应用层的数据加上TCP报头初识网络:IP、端口、网络协议、TCP-IP五层模型_革凡成圣211的博客-CSDN博客TCP/IP五层协议详解https://blog.csdn.net/weixin_56738054/article/details/128666970?spm=1001.2014.3001.5501

目录

  TCP报头的大致结构

4位首部长度(4个比特位):记录的是TCP报头的大小

 保留位(6位)

     为什么要有保留位

16位校验和   

32位序号&32位确认序号

TCP实现可靠性的方式:

方式一:确认应答机制

       存在问题分析:后发先制 

      存在问题原因

      解决后发先制问题的方案

      如何判断一个报文是否为应答报文

TCP的面向字节流特性在上述传输过程当中的体现

TCP实现可靠性的方式二:TCP超时重传问题

TCP时间阈值

 超时重传存在问题分析

去重操作 

快速重传


  TCP报头的大致结构

 TCP报文=TCP报头(首部长度)+TCP载荷 

 下面,将重点了解一下TCP报头的各个属性

【网络原理篇2】TCP报头详解_第1张图片


4位首部长度(4个比特位):记录的是TCP报头的大小

特点1:TCP报头的长度是可变的。不像UDP报头,大小为8个字节,长度不可变。变化的地方就是[选项长度]

特点2:4位首部长度,记录的是整个TCP报头的长度首部长度的值-20得到的就是选项部分的长度,单位为字节

一个字节的大小为8个比特位。那么,4个bit位范围为:(0,15)。

需要注意的是:此处的首部长度,单位是(4字节)


       如果首部长度显示的值为5,那么说明:此时TCP报头的实际大小为:5*4=20(字节),也就意味着,此时选项部分的长度为20-20=0字节,相当于没有字节数。

       如果首部长度显示的值为15,那么说明,此时TCP报头的实际大小为:15*4=60(字节),也就意味着,此时选项部分的长度为60-20=40字节

【网络原理篇2】TCP报头详解_第2张图片


 保留位(6位)

     为什么要有保留位

       如果后续TCP引入了一些新的功能,就可以使用保留位字段。

       如果引入了保留位,那么对于TCP原来的报头结构的影响就是比较小的,方便各个TCP版本之间的兼容。


16位校验和   

       此处TCP头部的的校验和与UDP头部的校验和效果类似,都是用于校验结果传输结果是否正确是一种方式。具体是怎样的,参考上一篇文章。


32位序号&32位确认序号

       这两个属性,和TCP协议的可靠性有关系。

       回顾一下:TCP协议的四个特点

       第一个:有连接;第二个:可靠传输;第三个:面向字节流;第四个:全双工。 下面,将重点讨论一下可靠性

       可靠性的含义:并不是发送方把所有的内容都发送给了接收方。

        不管有没有传输过去,作为发送方都可以知道传输过去与否。


TCP实现可靠性的方式:

方式一:确认应答机制

       有下面一个场景:

       小明给小红发送了一条消息:今天晚上吃什么?然后小红回应:今天晚上我想吃鱼

       当小红回复小明的时候,这个回复的内容,就被称为"应答报文"(acknowledge)。让小明知道小红回复他了。


       以上场景比较单一,也就是客户端发送一条消息,服务端就回应一次。

       那么,如果有这样的一个场景呢?

       小明先后连续对小红发了两句话:

        小明:小红,你今天晚上吃什么呀?......发送顺序①

        小明:小红,你穿的真漂亮呀!......发送顺序②

        按照常理,小红应该这样回应:

        小红:我今天晚上想吃鱼;......回应顺序①

        小红:谢谢你的夸奖!......回应顺序②


       存在问题分析:后发先制 

        比较迟发送的消息,优先于先发送的消息到达接收方。

        回到上面的场景,就变成这样了:

【网络原理篇2】TCP报头详解_第3张图片

       可以看到,在小明接收会话①的时候,也就是时间t5的时候,接到了小红后面发送的消息。

       按照常理,小红首先作出的回应①,应当在时间t5被小明接收,可是小明却在时间t6才接收到。


      存在问题原因

       两个主机之间,路线存在多条。数据报1和数据报2走的都是不同的路线,有的路线传输数据快,有的数据传输慢,情况是不可预期的。因此很有可能发生后发先制的


      解决后发先制问题的方案

      针对发送/回应的报文进行编号。

      作为主动发送报文的一方,报文当中应当明确发文的序号。

      作为反馈发送报文的一方,报文当中应当明确反馈给谁,也就是反馈报文当中需要指定此反馈的报文是针对哪一条主动发送的报文发送的。

        小明:

        小明:(发送①号报文)小红,你今天晚上吃什么呀?

        小明:(发送②号报文)小红,你穿的真漂亮呀!

        小红:

        小红:(针对①号报文):我想吃鱼

        小红:(针对②号报文):谢谢!

      【网络原理篇2】TCP报头详解_第4张图片

如上图,黑色框圈住的"针对①号","针对②号",就是反馈的对象。

再看一下TCP报头结构:

【网络原理篇2】TCP报头详解_第5张图片

       如果此报文为主动发送的一方(小明)发出主动报文,那么它的"32位确认序号"就为空。

       如果此报文为被动接收的一方(小红)发出的回应报文,那么"32位确认号"就为发送方的最大字节序号+1(下面会提到)

        这样,也就实现了TCP的可靠性传输,也就是确认应答机制


      如何判断一个报文是否为应答报文

       再看一下上面的TCP报头,可以看到,6位保留位的右侧有几列内容,其中有一列就是ack

       当ack这个标志位为1的时候,说明这个报文是一个应答报文。如果为0就不是应答报文了。

【网络原理篇2】TCP报头详解_第6张图片


TCP的面向字节流特性在上述传输过程当中的体现

TCP是面向字节流的形式进行传输的,并不是按照一条/两条这样的字符串格式进行传输的。

那么,在一次TCP会话当中,如何体现出TCP面向字节流的形式呢?

      TCP的数据报编号,是按照字节的方式来进行编号的。

      A给B发送一个字符串,这个字符串是由1000个字节构成的。

      TCP报头就只记录当前第一个字节的序号,假设第一个字节的序号为1

      那么,此时主机(A)发送的TCP报头当中记录的序号就为1,

       当主机(A)把数据发送到主机(B)上面的时候,主机(B)的应答报文当中的32位确认序号,应当填写的是1001

       关于主机(A)当中填写的32位序号为什么不是1,会在接下来的文章当中提到。


       当主机(A)再次发送其他数据的时候,就是从1001开始发送了,就是在刚才的1000的基础上面+1。

       所表示的含义:<1001的数据都收到了,A接下来应当从1001这个序号开始继续发送

 下图来源于网络,侵权删

【网络原理篇2】TCP报头详解_第7张图片

接收方回复发送方的32位确认序号有两个含义:

含义1:<确认序号的数据都已经被发送方收到了;

含义2:下次发送方发送的序号需要从当前确认序号开始。


TCP实现可靠性的方式二:TCP超时重传问题

 上面我们讨论确认应答的时候,其实是建立在了顺利传输的基础上面的。

 那么,下面,就需要讨论一下丢包的情况。

 什么是丢包呢?也就是发送的数据,没有得到对应的回应,这就是丢包。

 丢包,涉及两种情况:

 情况1:发送方把TCP报文发出去了,但是接收方没有接收到。

 情况2:发送方等待接收方返回报文的时候,返回的ack报文丢失了,接收方无法收到ack报文。

      总而言之,就是发送方看不到结果,没有收到ack,这两种情况会一视同仁,都认为是丢包了。

       因此,如果重新发送一下这个数据报,其实还是有很大的概论传输成功的,也就是在丢包的情况下,再次重新发送一次。


TCP时间阈值

       TCP直接引入了一个时间阈值。从发送方发出了一个数据之后,开始计时。如果在阈值的时间范围内没有得到对应的ack回应,那么就会再次发送一次,这个就是超时重传机制。

       关于这一个阈值究竟是多少,这个不太确定,不同的系统有不同的阈值。


 超时重传存在问题分析

       对于超时重传机制,看似没有什么问题。但是,很有可能让接收方接收到两次数据。

       也就是,发送方由于在阈值时间内没有收到ack,于是再次发送了一次。但是实际上主机B已经收到了。

图片来源于网络,侵权删除

【网络原理篇2】TCP报头详解_第8张图片

       这是一个支付的场景,当按下支付的按钮之后,系统自动从账户余额当中扣款1000,假

设此时设定的阈值为5ms。但是在5ms内,没有收到扣款成功的ack报文,于是再次发送扣款

1000的命令。这样,也就造成了多扣1000的尴尬情况。


去重操作 

       TCP对于重复发送的数据,是有一个特殊处理的方式,也就是去重。

       TCP存在一个"接收缓冲区"这样的存储空间。(这个缓冲区是在接收方的操作系统内核当中的一段内存)

       当主机B收到了主机A的数据之后,其实就是B的网卡读到了这一个数据,然后把这一个数据存放到B的缓冲区(这一个缓冲区相当于一个阻塞队列)当中。

       后续B主机使用getInputStream来read的时候,就是从接收缓冲区当中读取了。

       此时,读取的时候,会根据数据的编号,来判断当前接收缓冲区当中的两条数据是否是重复的。如果重复,那么新的数据就会被丢弃。

          这样,应用程序调用read读取到的数据就是不重复的了。

【网络原理篇2】TCP报头详解_第9张图片

       关于这个缓冲区,还有一点需要补充的,就是:

       TCP使用这个接收缓冲区,会对于收到的数据进行重新排序,使得应用程序跟收到(read)

的顺序跟发送的顺序一致。它就是根据收到的TCP报文序号进行排序,如果序号一致,那么

就去重。其中,B主机的缓冲区是一个优先级的阻塞队列,这个优先级就是TCP的序号


快速重传

            快速重传可以避免了超时重传的需要等待的问题。

            如果发送方发送的某一次syn报文出现了丢包;

       作为接收方,它对于发送方的恢复:只会反复应答丢包那一次的数据。

       快速重传的工作方式是:发送方当收到三个相同的 ACK 报文时,会在定时器过期之前,重传丢失的syn报文段

【网络原理篇2】TCP报头详解_第10张图片


TCP和UDP的一些区别(横向对比) 

一、和连接相关

跟连接相关的,TCP是有连接的协议,而UDP是无连接的协议。

TCP的有连接体现在发送方接受方三次握手上面。二者之间要进行通信必须要经过三次握手。


二、服务对象不一样

TCP的通信过程一定是服务端accept之后,再进行数据交互,也就是一条连接上面只有两个端点。

UDP支持一对一、一对多、多对多的交互通信。


三、可靠性相关

TCP可以保证数据无差错、不丢失、不重复、按序到达。

而UDP只是尽最大努力交付数据。

关于TCP的可靠性,主要就是以下几个方面(重要)

确认应答、重传机制(快速重传、超时重传)

流量控制、拥塞控制;

三次握手


四、发送速率控制方面

TCP有流量控制、拥塞控制两种控制速率的方式。

而UDP没有这两种方式,无法控制发送的速率。


五、传输方式的区别

           TCP是面向字节流的协议。没有边界,仅仅只是保证顺序和可靠。一个TCP报头可能包含多个TCP段。因此,TCP会产生粘包问题

          UDP是一个包一个包这样发送的,是有边界的。不会产生粘包问题。


六、分片不同

TCP数据报的大小如果超过了MSS大小,会在传输层进行分片。

UDP数据报的大小如果超过了MTU大小,会在网络层进行分片。


应用场景相关

TCP:由于它是可靠性地传输数据的。因此往往用于可靠性要求比较高的场景:

例如:

FTP文件传输;

HTTP/HTTPS;


 UDP:由于它不需要连接的建立就可以通信,可以随时发送数据,因此常常用于效率要求高的场景

例如:

同一个大型机房内的主机之间的通信;

视频、音频等多媒体通信;

广播通信。


TCP和UDP可以监听(绑定)同一个端口吗 

可以的

根本原因:

TCP和UDP传输协议,在内核当中是由两个完全独立的软件模块实现的。


主要体现:

       当主机收到数据报之后,可以在IP数据报当中查看到各自的传输层协议。然后再把这个数据交给各自的模块来处理。

【网络原理篇2】TCP报头详解_第11张图片


你可能感兴趣的:(网络,tcp/ip,网络协议)