linux网络 | TCP报头之六个标记位与部分可靠性策略

前言:本节内容讲述TCP报头里面的六个标记位以及一些保证TCP可靠性的方案(连接管理设计状态的分析滑动窗口占用篇幅大,放在下一节讲解)。 TCP可靠性方案也是学习TCP的一个重要的板块。 本节就来讲述一些可靠性方案。 下面废话不多说,开始我们的学习吧!

ps:本节内容需要一些前面学习的穿插内容, 友友们最好看一下这篇文章再来学习比较好哦:linux网络 | 传输层TCP | 认识tcp报头字段与分离-CSDN博客

目录

为什么要有六个标记位

六个标记位解析

ACK、SYN、FIN

PSH

RST

URG

可靠性策略

检验和

序列号

确认应答

超时重传


为什么要有六个标记位

服务器和客户端 1: n进行tcp通信的时候,一定要先建立连接,三次握手。然后结束通信,tcp也要断开连接四次挥手。在建立和断开之间,还要进行正常的数据通信,tcp在建立连接的时候一定要发送tcp的报文。 断开连接也要, 正常通信也好,都要发送tcp报文(至少要有报头, 可以没有数据)。所以,通信之前,有些tcp请求是用来建立链接的,有些是用来正常通信的,有些是用来断开连接的。 这就注定了tcp收到的报文, 本身是有类型的。

这个类型,接收方怎么知道报头的类型是什么呢? 所以就有了六个标记位 (区分tcp报文的类型)。

六个标记位解析

ACK、SYN、FIN

关于ACK,SYN,FIN很简单。 这三个是在三次握手和四次挥手的时候要使用的标记位。 具体就是:

  • ACK确认号是否有效,即确认应答
  • SYN请求建立链接;我们把携带SYN标识的称为同步报文段,即请求握手。
  • FIN: 通知对方,本端要关闭了

PSH

PSH是提示接收端应用程序立刻从TCP缓冲区把数据读走

什么意思, 就是说如果我们的发送方向对方发送数据,发送了大量的数据,导致对方的接收缓冲区已经满了。这个时候,会发生什么呢?

是不是就是不能再像对方的接收缓冲区发送数据,然后发送方就堵塞了!!! 但是,发送方堵塞不能一直堵塞,所以如果接受方的上层一直不处理接收缓冲区的报文,那么发送方就可以发送一个PSH报文。表示催促对方赶紧处理报文腾出位置! 即表示提示对方应该立刻把TCP缓冲区里面的报文读走。

RST

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

我们说TCP是保证可靠性的。那么是否建立连接,必须得成功呢?------tcp虽然保证可靠性,但是tcp允许链接建立失败。

我们要知道的另一个点是,一个客户端在服务端求接,这个时侯我们的服务定同时存在多个已经建立好的链接,这么务摊接,服务要对这么多接进行管理,关闭,所以服务端就要对这些链接进行管理。

所以,我们如何理解"链接"概念呢?

客户端和服务器双方建立好连接的本质,就是双方的操作系统内为链接创建struct结构体。这个链接结构体里面包含链接相关的属性,比如说链接什么时候建立、客户端的端口号等等。

我们也可以把链接结构体之间用指针相连,然后我们对连接的管理,就转化成了对链表的增删查改。
CS维护链接也是有成本的。这里的这个成本就是上面创建结构体,要花时间,要花空间。

在我们大量客户端进行连接时,就可能出现链接出现异常的情况。就比如客户端认为链接建立好了,但是服务器认为链接没有建立好, 这个时候客户端创建了结构体, 服务端没有创建, 这个成本就花在了客户端这边。 (后面我们会谈一下这个成本问题)

我们上面说CS是有成本的, 首先我们先不谈成本的解决方法, 先看一下为什么会有成本,我们用三次握手来细讲:

这些请求的线之所以不直直的画,就是因为从请求发送到拿到请求之间是有时间差的。

上面的三次握手中有一个小问题,就是在客户端最后一次ACK的时候,是在客户端发出ACK后就认为建立连接成功了呢,还是要知道服务器已经收到ACK后客户端才会认为连接已经建立好呢?

这里的答案是,只要发出去,就认为连接成功,没有应答!!!!

所以tcp三次握手, 本质上是在赌, 赌最后的ACK服务端能够收到。但是前两次握手的可靠性是能够保证的,不能保证的只有最后一个ACK。

  • 所以,client在三次握手中,认为只要把三次握手中的第三次报文发出,就认为连接建立好了!!!
  • 如果ACK丢失了,此时服务端就认为这个连接没有建立好,此时就是客户端和服务端对连接是否建立成功认知不一致。然后客户端这个时候发消息,此时服务端认为连接还没有建立好,就会应答RST标记回去,重新建立连接。重新三次握手。

综上, RST是客户端和服务器,双方对连接认知不一致,即连接建立异常的情况下重新连接使用的。

URG

URG是紧急指针是否有效

  • 有些情况下,想要让上层高优先级去处理一些数据,此就可以设置一个URG标志位,此URG标记位如果为0,表示无效,16位紧急指针没有意义,填写一个0即可。
  • 但是URG如果为1,表示这个报文内部包含了紧急数据,要求当前要紧急处理,这个16位紧急数据就代表在整个tcp数据当中,紧急数据的偏移量是多少。紧急数据只允许是一个字节。

什么情况下我们会使用这个紧急数据呢?

假如这个服务端很卡,所以客户端就要询问他为什么这么卡。这个时候客户端就要向服务端发起询问,询问服务器是怎么回事, 所以我们就需要服务端支持读取紧急数据 + 软件功能提供状态编号

假如服务端这个时候很卡,我们发送了多少数据都没有回应。这个时候我们就可以发一个紧急数据,这个紧急数据,在服务端内有专门的位置读取这个紧急数据。然后服务端读取这个紧急数据,读上来之后,因为处理的信息量不大,然后服务端就要把状态返回给客户端(比如1,2,3)这样询问和响应的数据就加快了。

可靠性策略

检验和

十六位检验和, 报头中的字段,和UDP的一样, 都是检验数据在传输过程中有没有出现偏差。

序列号

32位序号, 避免了数据包乱序的问题和数据包的重复问题(每一个序号只有一条报文)

确认应答

保证了确认应答消息之前的消息的可靠性。 值得一提的是, 确认应答, 起始就是ACK,所以就是ACK应答机制。

超时重传

上一节的超时重传我们有一些细节没有讲到, 这一节我们补充一些:

为什么要有超时重传,主机A在向主机B发送数据时,如果是数据本身丢失了。即主机B根本就不知道A给他发过数据。所以B也就不会给A进行应答。那么A就收不到B的应答,他就不知道自己刚刚的报文到底有没有被B收到。

所以为了给丢了做一个定义,就规定了一个特定的时间间隔,凡是超过这个时间间隔的报文,如果没有收到应答,那么就当成丢了。超时之后,当成丢了之后,就要开始重新发送报文, 这个就叫做超时重传机制。

另外还有一种情况就是主机A给主机B发送消息。主机B收到了消息,发送回去确认应答,但是确认应答丢了,主机A同样收不到应答,超过特定时间间隔后,主机A就要进行超时重传。

对于第一种情况,主机A确认丢失后重发就重发了。但是第二种情况下,主机B明明收到了主机A的报主机A还要重新发,就势必会造成主机B收到 重复报文重复报文也是一种不可靠情况,所以就要去重。所以这里又用到了序号。

序号是如何设置的呢?

设定特定时间间隔怎么设置呢。这个我们就要思考一个问题。

就是如果此时网络速度很快,那么这个时间间隔就不能太长。因为如果时间太长,在网络速度很快的情况下就非常浪费时间。

如果此时网络速度很慢,那么这个时间间隔就不能太短,因为如果时间太短,在网络速度很慢的情况下,就很容易发送一个报文,这个报文就发生超时,然后重传。这样就容易发送大面积重传的现象。

所以,我们就可以得到一个结论,超时重传的时间一定是动态的,是随着网络情况发生变化的。

操作系统中的解决方案是:Linux中(BSD Unix和Windows也是如此),超时以500ms为一

个单位进行控制,每次判定超时重发的超时,时间都是500ms的整数倍 。

如果重发一次之后,仍然得不到应答,等待 2*500ms 后再进行重传。如果仍然得不到应答等待 4*500ms 进行重传依次类推, 以指数形式递增,累计到一定的重传次数,TCP认为网络或者对端主机出现异常,强制关闭连接。

------------------以上就是本节全部内容哦, 如果对友友们有帮助的话可以关注博主, 方便学习更多知识哦!!!

相关推荐
Main. 242 小时前
Linux的基本指令(上)
linux·服务器
头铁散人4 小时前
IMX6ull项目环境配置
linux·运维·服务器
qq_392794485 小时前
为什么 TCP 挥手需要有 TIME_WAIT 状态?
网络·网络协议·tcp/ip
闲猫6 小时前
正向代理(动态 IP 代理)和反向代理
网络·网络协议·tcp/ip
怡步晓心l6 小时前
Linux下Ubuntun系统报错find_package(BLAS REQUIRED)找不到
linux·运维·服务器
一尘之中6 小时前
IPoIB(IP over InfiniBand)数据接收与发送机制详解
网络·tcp/ip·php
hvinsion6 小时前
Python 轻松扫描,快速检测:高效IP网段扫描工具全解析
网络·python·tcp/ip
惊鸿一博6 小时前
ubuntu_查询连接当前服务器的用户ip
服务器·tcp/ip·ubuntu
SomeBottle8 小时前
【小记】在 Google Colab 等平台上运行 GPU 容器
linux·python·docker·学习笔记·容器化·斩虫
金灰8 小时前
Linux文本处理三剑客:awk、sed、grep
linux·运维·服务器·chrome·安全