【Linux】传输层协议:TCP/UDP

目录

netstat

pidof

UDP协议

TCP协议

TCP协议段格式

TCP协议的相关机制

确认应答(ACK)机制

超时重传机制

连接管理机制

服务端状态转换 

客户端状态转化

流量控制

 流量控制常见问题:

滑动窗口 

拥塞控制

延迟应答

面向字节流

粘包问题

TCP异常情况


传输层的作用就是负责数据能够从发送端接收数据

端口号

端口号(Port)标识了一个主机上进行通信的不同应用程序;

 在TCP/IP协议中,用“源IP”,“源端口号”,“目的IP”,“目的端口号”,“协议号”这样一个五元组来标识一个通信(可以通过netstat -n查看)

端口号范围的划分

0 - 1023:知名端口号,HTTP,FTP,SSH 等这些广为使用的应用层协议,他们的端口号都是固定的。

认识知名端口号

有些服务器是非常常用的 , 为了使用方便 , 人们约定一些常用的服务器 , 都是用以下这些固定的端口号 :
  • ssh服务器, 使用22端口
  • ftp服务器, 使用21端口
  • telnet服务器, 使用23端口
  • http服务器, 使用80端口
  • https服务器, 使用443

执行下面的命令,可以看到知名端口号

cat /etc/services 

两个问题

  • 一个进程是否可以bind多个端口号?
  • 一个端口号是否可以被多个进程bind?

netstat

 netstat是一个用来查看网络状态的重要工具

语法 netstat [ 选项 ]
功能 :查看网络状态
常用选项
  • n 拒绝显示别名,能显示数字的全部转化成数字
  • l 仅列出有在 Listen (监听) 的服務状态
  • p 显示建立相关链接的程序名
  • t (tcp)仅显示tcp相关选项
  • u (udp)仅显示udp相关选项
  • a (all)显示所有选项,默认不显示LISTEN相关

pidof

在查看服务器的进程 id 时非常方便 .
语法 pidof [ 进程名 ]
功能 :通过进程名 , 查看进程 id,常用来查看守护进程

UDP协议

UDP协议端格式

UDP长度-8字节(报头)= 有效载荷的长度 

  • 16UDP长度, 表示整个数据报(UDP首部+UDP数据)的最大长度;
  • 如果校验和出错, 就会直接丢弃;

TCP协议

        TCP全称为 "传输控制协议(Transmission Control Protocol"). 人如其名, 要对数据的传输进行一个详细的控制; 

TCP协议段格式

4位的首部长度描述的报头的长度,计算的时候,有基本的大小单位:4字节 

例如 x*4=20 ,x取5 也就是0101

如果不进行流量控制,会导致大面积丢包 

16位窗口大小就是对方接收缓冲区剩余空间,也就是进行流量控制的依据

tcp协议不同于http协议的是双方都会进行收发数据

TCP最基本、最原始的通信过程

        收到应答信号,确认最近发送的信息对方收到了,没有应答的数据,我们无法保证可靠性,所以,最新的一条信息,是没有应答的,所以我们无法保证发出去的信息是100%可靠的。

综上,世界上是不存在100%可靠的网络协议,但是局部性的可靠性是可以保证的。

一段时间后,如果没有收到应答,就认为数据丢失了,进行重传。

将应答和下一个TCP数据二合一发送给对方,这种策略称为捎带应答

乱序问题

那么接下来有一个问题,如果客户端发送tcp数据给服务器,服务器没有返回应答信号,客户端是否继续发送下一条数据?

如果采用发一条数据,应答一个的方式,效率会很低,因此客户端一般一次给服务器发送一批数据

服务器数据的接收顺序并不一定是客户端发送数据的顺序 ,这种问题称为数据包乱序问题。这种情况如果不解决,直接将数据交到缓冲区,会导致应用层解析数据报文错误。造成乱序本身就是不可靠的一种。

为了解决这种问题,引入序号,给每个报文加上序号,发送到服务端,即使服务端收到的是乱序的,也可以通过序号进行还原。

如下图所示:

综上,也就是说32位序号是为了保证数据的按序到达

 服务端接收到客户端的一批tcp数据后,会返回多个应答数据,那么怎么区分某个应答是对应哪个tcp数据呢?

确认序号:填充的是它收到的报文的序号+1

为什么要这么规定?

确认序号的意义:表示确认序号之前的数据,已经全部收到了,下一次发送,请从确认序号指定的数字开始发送!!

当应答返回3001,而2001、1001未返回相应应答 ,服务端默认3001之前已经全部收到了,这样的规定允许应答能有少量的丢失。

tcp收到的报文一定是由各种“类型”的,不同的类型,决定了服务端做不同的动作!接收方如何得知报头的类型是什么?用6个标记位,标记位存在的意义:区分tcp报文的类型

ACK :确认序号是否有效

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

FIN:通知对方,本端要关闭了

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

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

URG:紧急指针是否有效

16位紧急指针:当前报文包含紧急数据的偏移量是多少,紧急数据为一个字节,称为带外数据,缓冲区排队的数据是常规数据

三次握手

TCP协议的相关机制

综上所述,我们可以总结出TCP协议的几个机制:

确认应答(ACK)机制

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

超时重传机制

  • 主机A发送数据给B之后,可能因为网络拥堵等原因,数据无法到达主机B;
  • 如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发。 

但是主机A未收到B的确认应答,也可能是ACK丢失了。

        因此主机B 会收到很多重复数据 . 那么 TCP 协议需要能够识别出那些包是重复的包 , 并且把重复的丢弃掉 . 这时候我们可以利用前面提到的序列号, 就可以很容易做到去重的效果 .
那么超时的时间,也就是这个特定的时间间隔是怎么确定的呢?
  • 最理想的情况下, 找到一个最小的时间, 保证 "确认应答一定能在这个时间内返回".
  • 但是这个时间的长短, 随着网络环境的不同, 是有差异的.
  • 如果超时时间设的太长, 会影响整体的重传效率;
  • 如果超时时间设的太短, 有可能会频繁发送重复的包

TCP为了保证无论在任何环境下都能比较高性能的通信, 因此会动态计算这个最大超时时间.

  • Linux(BSD UnixWindows也是如此), 超时以500ms为一个单位进行控制, 每次判定超时重发的超时 时间都是500ms的整数倍.
  • 如果重发一次之后, 仍然得不到应答, 等待 2*500ms 后再进行重传.
  • 如果仍然得不到应答, 等待 4*500ms 进行重传. 依次类推, 以指数形式递增.
  • 累计到一定的重传次数, TCP认为网络或者对端主机出现异常, 强制关闭连接.

连接管理机制

服务端状态转换 

[CLOSED -> LISTEN] 服务器端调用listen后进入LISTEN状态,等待客户端连接。

[LISTEN -> SYS_RCVD] 一旦监听到连接请求(同步报文段SYN),就将该连接放入内核等待队列中,并向客户端发送SYN确认报文

[SYS_RCVD -> ESTABLISHED] 服务端一旦收到客户端的确认报文,就进入ESTABLISHED,可以进行读取数据

 [ESTABLISHED -> CLOSE_WAIT] 当客户端主动关闭连接(调用close),服务器会收到结束报文段,服务器返回确认报文段并进入CLOSE_WAIT;

[CLOSE_WAIT -> LAST_ACK] 进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前的数据); 当服务器真正调用close关闭连接时, 会向客户端发送FIN, 此时服务器进入LAST_ACK状态, 等待最后一个 ACK到来(这个ACK是客户端确认收到了FIN)
[LAST_ACK -> CLOSED] 服务器收到了对FIN的ACK, 彻底关闭连接

客户端状态转化

[CLOSED -> SYN_SENT] 客户端调用connect, 发送同步报文段;
[SYN_SENT -> ESTABLISHED]  connect调用成功, 则进入ESTABLISHED状态, 开始读写数据;
[ESTABLISHED -> FIN_WAIT_1] 客户端主动调用close时, 向服务器发送结束报文段, 同时进入
FIN_WAIT_1;
[FIN_WAIT_1 -> FIN_WAIT_2] 客户端收到服务器对结束报文段的确认, 则进入FIN_WAIT_2, 开始等待服务器的结束报文段;
[FIN_WAIT_2 -> TIME_WAIT] 客户端收到服务器发来的结束报文段, 进入TIME_WAIT, 并发出LAST_ACK;
[TIME_WAIT -> CLOSED] 客户端要等待一个2MSL(Max Segment Life, 报文最大生存时间)的时间, 才会进入CLOSED状态.

为什么采用三次握手?

一次的话容易受到SYN洪水攻击 ,两次的话连接失败的成本会嫁接到服务器上

四次挥手可以改成三次吗?

当发送关闭信号时,便不再发送数据,只发送一些ACK报文。

四次挥手过程如下:

1.客户端:我要关闭了  //第一次挥手

2.服务器:好的我知道了(ACK) //第二次挥手

3.此时服务器可能还有未发送完毕的正常业务数据,等发送完毕后再说:我要关闭了 //第三次挥手

4.客户端:好的我知道了 //第四次挥手

如果第三步服务器正好没有业务数据要发送了,可用捎带应答,实现三次挥手

PS:listen的第二个参数?backlog+1,表示底层已经建立好的连接队列的最大长度

全连接队列的大小为什么不能太长?

没必要太长 ,服务器没时间消耗连接时,还需要更多的内存来维护这个连接

为什么不能没有全连接队列?

因为如果没有全连接队列的话,一旦服务器当前资源空闲,上层无法快速补齐,导致服务器资源无法被充分消耗

一个网络报文在网络里存活的时间称为MSL

TIME_WAIT:等多长时间,为什么?

两个MSL即相当于一个报文的一来一回

  • 让通信双方历史数据得以消散
  • 让我们断开连接,4次挥手,具有较好的容错性

从客户端传送到服务端这个时间称为最大传送时长

报文在网络存在的时间称为最大存在时长

流量控制

        接收端处理数据的速度是有限的. 如果发送端发的太快 , 导致接收端的缓冲区被打满 , 这个时候如果发送端继续发送 , 就会造成丢包, 继而引起丢包重传等等一系列连锁反应 . 因此TCP 支持根据接收端的处理能力 , 来决定发送端的发送速度 . 这个机制就叫做 流量控制 (Flow Control);    
  • 接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 "窗口大小" 字段, 通过ACK端通知发送端;
  • 窗口大小字段越大, 说明网络的吞吐量越高;
  • 接收端一旦发现自己的缓冲区快满了, 就会将窗口大小设置成一个更小的值通知给发送端;
  • 发送端接受到这个窗口之后, 就会减慢自己的发送速度;
  • 如果接收端缓冲区满了, 就会将窗口置为0; 这时发送方不再发送数据, 但是需要定期发送一个窗口探测数 据段, 使接收端把窗口大小告诉发送端

接收端如何把窗口大小告诉发送端呢 ? 回忆我们的 TCP 首部中 , 有一个 16 位窗口字段 , 就是存放了窗口大小信息 ;
那么问题来了 , 16 位数字最大表示 65535, 那么 TCP 窗口最大就是 65535 字节么 ?
实际上 , TCP 首部 40 字节选项中还包含了一个窗口扩大因子 M, 实际窗口大小是 窗口字段的值左移 M ;
这个窗口扩大因子选项如下图所示:

 流量控制常见问题:

1.第一次发送数据的时候,怎么保证发送的数据量是合理的?

        三次握手时,双方交换了报文,同时也协商了双方的接收能力。
        第三次握手的时候,可以携带数据,先识别ACK。前两次是不许携带数据。
2.流量控制,属于可靠性,还是属于效率?
        属于可靠性,防止正常丢包,变相提高了效率

滑动窗口 

滑动窗口是我们发送端缓冲区的一部分。至于区域划分可以理解成通过双指针(下标)进行区分即可。

滑动窗口的大小,不能超过对方的接收缓冲区的剩余空间的大小,即应答报文的窗口大小

情况1:如果丢包了,怎么理解滑动窗口

        如果我们成功发送2001之前的报文,也得到了接收方返回的ACK报文,3001位置发生丢包,4001,5001得到了接收方返回的ACK报文,我们在进行窗口滑动时,会在2001位置停下来,等待3001位置进行重发得到ACK报文,在加上之前我们对确认序号的定义:确认序号是x,x之前的报文我们全部都收到了,综上保证了滑动窗口连续的向后更新,不会出现跳跃的情况,也就是跳过丢包的报文。

情况2:数据包直接丢了

发送方连续三次收到同样的确认应答时则进行重发,这种方式称为快重传 。

已经有了快重传,为什么还要有超时重传?

快重传是有条件的,连续三次收到同样的确认应答才进行快重传,如果后面没有那么多数据发送,就不会触发快重传,因此快重传是提高效率的,超时重传相当于是兜底的。

问题2:滑动窗口可以向左移动吗?会向右移动吗?移动的时候,大小会变化吗?怎么变化?会为0吗?

不可以向左移动,因为滑动窗口本身划分的数据区域左侧是已经发送已经确认的。

右不变,做移动,范围缩小,左右都移动,范围扩大;

移动的时候,大小会动态变化

如果为0,发送方会进行窗口探测,如下进行更改大小

滑动窗口 start = 根据确认序号设置

                end=确认序号+min(窗口大小,有效数据区域大小)

因此流量控制是通过滑动窗口实现的,通过控制滑动窗口大小

问题3:滑动窗口会在发送缓冲区越界吗?

不会,tcp采用了类似环状的算法

拥塞控制

如果发送数据,出现问题,不仅仅是对方主机出现问题,也有可能是网络出现问题

  1. 如果通信的时候,出现少量的丢包(常规情况)
  2. 如果通信的时候,出现大量的丢包(网络出现了问题)
  • 硬件设备出现问题
  • 数据量太大,引起阻塞

如果通信双方出现了大量的数据丢包问题(滑动窗口内大量的数据都超时了),tcp会判断网络出现问题了(网络拥塞了)

我们发送方应该怎么办?我们不能立即对报文进行超时重发,否则会加重网络拥塞。

延迟应答

如果接收数据的主机立刻返回 ACK 应答 , 这时候返回的窗口可能比较小 .
  • 假设接收端缓冲区为1M. 一次收到了500K的数据; 如果立刻应答, 返回的窗口就是500K;
  • 但实际上可能处理端处理的速度很快, 10ms之内就把500K数据从缓冲区消费掉了;
  • 在这种情况下, 接收端处理还远没有达到自己的极限, 即使窗口再放大一些, 也能处理过来;
  • 如果接收端稍微等一会再应答, 比如等待200ms再应答, 那么这个时候返回的窗口大小就是1M;
一定要记得 , 窗口越大 , 网络吞吐量就越大 , 传输效率就越高 . 我们的目标是在保证网络不拥塞的情况下尽量提高传输效率;
那么所有的包都可以延迟应答么 ? 肯定也不是 ;
  • 数量限制: 每隔N个包就应答一次;
  • 时间限制: 超过最大延迟时间就应答一次;
具体的数量和超时时间 , 依操作系统不同也有差异 ; 一般 N 2, 超时时间取 200ms;

面向字节流

创建一个 TCP socket, 同时在内核中创建一个 发送缓冲区 和一个 接收缓冲区 ;
  • 调用write, 数据会先写入发送缓冲区中;
  • 如果发送的字节数太长, 会被拆分成多个TCP的数据包发出;
  • 如果发送的字节数太短, 就会先在缓冲区里等待, 等到缓冲区长度差不多了, 或者其他合适的时机发送出去;
  • 接收数据的时候, 数据也是从网卡驱动程序到达内核的接收缓冲区;
  • 然后应用程序可以调用read从接收缓冲区拿数据;
  • 另一方面, TCP的一个连接, 既有发送缓冲区, 也有接收缓冲区, 那么对于这一个连接, 既可以读数据, 也可以写数据. 这个概念叫做 全双工
由于缓冲区的存在 , TCP 程序的读和写不需要一一匹配 , 例如 :
  • 100个字节数据时, 可以调用一次write100个字节, 也可以调用100write, 每次写一个字节;
  • 100个字节数据时, 也完全不需要考虑写的时候是怎么写的, 既可以一次read 100个字节, 也可以一次read一个字节, 重复100;

粘包问题

面向字节流衍生出来的问题,接收一个半或者半个(不完整的报文);

如何解决用户层的粘包问题?

  1. 定长报文:在应用层通过自定义协议,明确报文和报文之间的边界
  2. 使用特殊字符
  3. 使用自描述字段+定长报头
  4. 使用自描述字段+特殊字符

对于UDP协议来说, 是否也存在 "粘包问题" ?

  1. 对于UDP, 如果还没有上层交付数据, UDP的报文长度仍然在. 同时, UDP是一个一个把数据交付给应用层. 就有很明确的数据边界.
  2. 站在应用层的站在应用层的角度, 使用UDP的时候, 要么收到完整的UDP报文, 要么不收. 不会出现"半个"的情况。

TCP异常情况

1)进程终止

连接正常自动断开,因为tcp连接是和文件直接相关的,文件的生命周期是随进程的。

2)机器重启

先杀掉所有的进程

3)机器掉电/网线断开

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/473213.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp ios证书失效

前面是按照网上查找的方法 作者大大的地址 1、一个ios账户(688付费版) 2、登录 Apple Developer 3、创建Identifiers ps:创建时需继承苹果的sdk,只需要一个就行 点击continue再点击Register即可 4、创建.cer证书 &…

OpenAI CEO透露GPT-4表现“有点糟糕”;通义听悟音视频问答登场;Adobe整合AI功能助力3D设计创作

🦉 AI新闻 🚀 OpenAI CEO透露GPT-4表现“有点糟糕” 摘要:OpenAI的首席执行官Sam Altman在与Lex Fridman的访谈中表示,GPT-4的表现并不令人满意,认为其“有点糟糕”,同时对即将到来的GPT-5寄予厚望。Altm…

联想笔记本的声音键没有反应怎么办?

如果我的联想笔记本电脑上的声音按钮没有响应,该怎么办? 如果我的联想笔记本电脑上的声音按钮没有响应,该怎么办? 按下按钮后我无法控制声音。 我该怎么办? 以下是我为您整理的关于联想笔记本声音按键无反应的相关资料…

Power BI学习(数据可视化)

另一个也可以的工具是:Tableau 还有一个是:神策,主要是用于互联网的app的数据埋点 数据分析的过程: 数据源--数据清洗(power query)-构建指标 新建度量值(power pivot)-可视化&…

【重温设计模式】策略模式及其Java示例

策略模式的基本概念 策略模式,是一种常见的行为设计模式,主要用于处理程序中的一些相同行为,但具有不同实现方式的问题。在策略模式中,我们将每一种行为封装为一个个策略类,通过策略类的组合和切换,可以灵…

数据仓库的魅力及其在企业中的应用实践

数据仓库,这一创新性的概念来自于比尔恩门,从1980年代末提出以来,便凭借其独特的架构设计和强大的数据处理能力,在全球商业领域中掀起了一场革命。它不仅是解决企业海量数据存储和查询需求的关键技术,更是推动企业实现…

MYSQL数据库管理基本操作

一、数据库的基本操作 1、登录数据库 [rootmysql-server ~]#mysql -uroot -p123456 ###直接回车,则进入数据库[rootmysql-server ~]#mysql -u root -p ###直接回车 Enter password: ###输入密码 方法一&#xff1a…

第3关:创建零件表P,并插入数据

任务描述 零件表P由零件代码(PNO)、零件名(PNAME)、颜色(COLOR)、重量(WEIGHT)组成。创建零件表P(PNO,PNAME,COLOR,WEIGHT),并在P表中插入下图数据。 相关知识 1、MySQL创建表的基本语法如下: 其中,table_name 是要创…

docker入门(六)—— docker镜像详细介绍,理解docker分层

docker 镜像详解 镜像本质是什么 镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。 别人给我们生成好的一个环境&…

【黄金手指】windows操作系统环境下使用jar命令行解压和打包Springboot项目jar包

一、背景 项目中利用maven将Springboot项目打包成生产环境jar包。名为 prod_2024_1.jar。 需求是 修改配置文件中的某些参数值,并重新发布。 二、解压 jar -xvf .\prod_2024_1.jar释义: 这段命令是用于解压缩名为"prod_2024_1.jar"的Java归…

期刊如何反击一波可疑图像

出版商正在部署基于人工智能的工具来检测可疑图像,但生成式人工智能威胁着他们的努力。 期刊正在努力检测用于分析蛋白质和DNA的凝胶的操纵图像。图片来源:Shutterstock 似乎每个月都会有一系列针对研究人员的新高调指控,这些研究人员的论文…

软件的安装与卸载(YUM)

YUM:yum 是一个方便的"应用商店",你可以通过它轻松地安装、更新和删除软件包,就像从应用商店中下载和安装应用程序一样。(这个得用root身份,普通用户权限不够) 常用命令: 1.安装软件…

阿里云2核4G服务器支持多少人在线?2C4G多少钱一年?

2核4G服务器支持多少人在线?阿里云服务器网账号下的2核4G服务器支持20人同时在线访问,然而应用不同、类型不同、程序效率不同实际并发数也不同,2核4G服务器的在线访问人数取决于多个变量因素。 阿里云2核4G服务器多少钱一年?2核4…

python_django网红基地孵化园场地管理系统flask

作为一个管理孵化园的网络系统,数据流量是非常大的,所以系统的设计必须满足使用方便,操作灵活的要求。所以在设计孵化园管理系统管理系统应达到以下目标: (1)界面要美观友好,检索要快捷简易&…

3.20网络编程

练习: 1> 创建一个工人信息库,包含工号(主键)、姓名、年龄、薪资。 2> 添加三条工人信息(可以完整信息,也可以非完整信息) 3> 修改某一个工人的薪资(确定的一个&#xf…

应用改进SA算法实现MATLAB-HFSS交互仿真与天线优化

应用改进SA算法实现MATLAB-HFSS交互仿真与天线优化 第一章SA算法及其简单应用1.1 SA算法简介1.2 SA算法原理1.2.1 SA算法原理 1.3 Metropolis准则及退火过程中的参数控制1.3.1 Metropolis准则1.3.2退火过程中的参数控制 1.4 SA算法简单应用 第二章 改进SA算法2.1 改进方向2.2 改…

企业如何选择一个开源「好」项目?

开源 三句半 oss-roast 需求明确是关键 风险考量要周全 开源虽好不白捡 别忘合规! 显然,开源已成为一股不可阻挡的洪流,企业拥抱开源,积极参与开源项目不仅是响应技术潮流的必然选择,更是实现自身技术创新、市场拓展等…

新火种AI|国产手机抢滩“AI+折叠屏”赛道,行业洗牌大战就此开启?

作者:小岩 编辑:彩云 从2023年到2024年,随着新一波人工智能浪潮的加速,消费电子产品也迎来了全新的话题——AI。更重要的是,这场战争看似没有硝烟,但各大厂商都已经暗自角力了许久,特别是手机…

PHP全新美化广告横幅在线制作源码

源码简介 可以做网站的引流不需要安装上传就可以使用,在第一版基础上做了二次开发更加好用 注意:主机和服务器均可架设搭建,如果使用宝塔架设点击访问的时候提示找不到文件路径的时候,记得点击网站目录把防跨站攻击先关闭,这样就可以正常访问了,这款是…

华为openEuler系统卸载jdk

华为openEuler系统卸载jdk 1.查看openEuler上已安装的 Java 版本: 在终端中运行以下命令,查看系统中已经安装的 Java 版本。 sudo alternatives --config java这将列出已安装的 Java 版本,你可以看到当前使用的是哪个版本 2.卸载 Java&am…