网络协议(二)传输层(UDP、TCP)

2025-11-02 13:42:23 装备掉落 1932

目录

一、UDP协议

① 协议实现

② 协议特性

③ 编程影响

④ 基于UDP的应用层协议

二、TCP协议

① 协议实现

② 协议特性:面向连接、可靠传输、提供字节流传输服务

面向链接:

1、三次握手建立连接:

2、四次挥手断开连接:

3、TCP连接管理中的保活机制:

可靠传输:

1、流量控制:滑动窗口机制

2、停等协议:

3、回退N步协议:

4、选择重传协议:

5、拥塞控制:

6、快速重传协议:

字节流传输:

1、粘包问题:

一、UDP协议

UDP是User Datagram Protocol的简称,中文名是用户数据报协议

① 协议实现

就是在应用层交付给自己的数据前封装了一个UDP报头

16位源端口号,16位目的端口号:描述通信俩端进程是谁

16位数据报长度:长度字段指定了该数据报的总长度(该字段大小也限制了传输数据报长度必须小于64K-8)

16位校验和:校验数据一致性

② 协议特性

无连接:通信时,不需要建立链接,只要知道对方地址就可以发送数据

不可靠:不保证数据有序,且安全的到达对端(没有丢包检测以及重传机制)

面向数据报:整条交付,有最大长度限制的传输方式

③ 编程影响

UDP传输数据有最大长度限制,必须小于64K-8,如果数据过大就需要在应用层进行分包操作

UDP不保证数据有序且安全的到达对端,因此传输多个数据时, 应用层需要做出包序管理(保证传输包的顺序),如果对可靠有要求,则需要再应用层实现对应的丢包检测以及重传机制

UDP传输是整条交付的,不会交付半条或者多条数据,在应用层接收数据时,缓冲区就必须定义的足够大,能够确保至少获取完整的一条数据。

④ 基于UDP的应用层协议

NFS:网络文件系统

TFTP:简单文件传输协议

DHCP:动态主机配置协议

BOOTP:启动协议

DNS:域名解析协议

二、TCP协议

传输控制协议

(Transmission Control Protocol").

人如其名

,

要对数据的传输进行一个详细的控制

① 协议实现

32位序号:

4位头部长度:以4字节为单位描述TCP报文头部长度,TCP报头最长是60字节,最小20字节

解析过程:先取出20字节固定长度数据,然后根据头长取出选项数据

(这20字节就是结构的前五行,每行4字节)

说白了这个字段就说明TCP传输层在这条数据里面占多少,拿出来之后剩下的就是应用层数据

6位保留:展示未使用

6位标志位:FIN、SYN、RST、PUSH、ACK、URG

FIN:表示断开链接

SYN置1:这个标志位表示一个连接建立请求

RST:reset 表示重新建立请求

PUSH:要求 尽快将数据取出

ACK:确认应答

URG:紧急指针

16位窗口大小:用于实现滑动窗口机制,进行流量控制

16位校验和:二进制反码求和算法,校验数据一致性

16位紧急指针:指向紧急优先带外数据的结束位置

② 协议特性:面向连接、可靠传输、提供字节流传输服务

面向链接:

通信前,要先建立链接,确保双方都是在线,具有数据收发能力的。

连接管理:三次握手建立链接,四次挥手断开链接

1、三次握手建立连接:

通信前,要先建立链接,确保双方具有数据收发能力的。

为什么握手是三次?

俩次不安全,四次没必要

俩次不安全:通信双方都要确认双方是否具有数据收发能力,因此都要进行SYN确认

1、合并前俩步,有可能SYN会延迟到达,与重发的SYN形成冲突

2、防止恶意攻击,比如客户端发送SYN后直接退出

四次没必要(没必要发送俩次报文,再一次回复中将对应比特位置一即可)

握手失败了,俩端是如何处理的:

第一次握手失败:客户端会重传请求SYN

第二次握手失败:服务端在等待最后一次ACK超时后发送一个RST然后释放资源。

客户端会重传SYN

第三次握手失败:服务端在等待最后一次ACK超时后发送一个RST然后释放资源。

2、四次挥手断开连接:

通信结束了,会有一个断开连接过程,避免出现意外情况。

FIN请求的功能:只能表示不再给对方发送数据(不代表不接收数据)

CLOSE_WAIT:等待关闭,对方发送了FIN包,已经不再给自己发送数据,上层如果这时候还在继续recv,则会读完缓冲区数据后,不再阻塞,而是返回0。这种情况下就是等待上层针对这种情况处理。

1、挥手为什么是四次:

1、FIN请求只能表示主动关闭方不再发送数据,不代表不再接收数据,因此,被动关闭方收到FIN并进行确认后,还有可能会继续发送数据等待上层不再发送数据了,也要关闭套接字了才会发送FIN包,因此中间的ACK和FIN不能进行合并

2、一台主机上出现了大量的CLOSE_WAIT状态连接,是什么原因?

只有收到了FIN请求并进行了确认回复的连接会进行CLOSE_WAIT,

但是再后续没有进行close操作导致一直处于CLOSE_WAIT状态,无法发送FIN,

原因就是代码中没有针对断开连接的套接字进行关闭处理。

3、TIME_WAIT状态有什么用,为什么不直接关闭套接字释放资源?

TIME_WAIT是主动关闭方在收到被动关闭方发送ACK和FIN之后,再向被动关闭方发送了一个ACK确认后,自身处于的一种状态TIME_WAIT,随后再等待2个MSL(报文在网络中存在的最大生命周期,默认60s)之后成为CLOSED状态

可是为什么要这样呢?

因为有这样一个可能,就是被动方没有收到最后一次ACK(上图中的红叉),那么它就会给主动方重新发送一份FIN请求,然后主动方又会重新发送一个ACK,存在这样一个确认的过程。

并且,如果此时发送ACK之后退出了,没有TIME_WAIT,主动方直接关闭了套接字释放资源,有可能出现新启动的套接字使用了之前相同的地址信息,而后续被动关闭方又会重传FIN,就会导致上一次通信因为ACK最后一次丢失,遗留的问题(重传FIN)对新链接造成影响。

所以需要等待俩个MSL时间,针对有可能存在的FIN重传进行处理,并保证上一次通信的所有数据都消失在网络中。

4、一台主机上出现了大量的TIME_WAIT状态连接,是什么原因,如何处理?

TIME_WAIT是主动关闭方发送最后一次 ACK后进入的状态,等待一段时间是为了处理有可能因为FIN丢失导致的FIN重传的处理。

因此一台主机出现大量TIME_WAIT连接,是因为主机上大量的主动关闭了连接,常见于爬虫服务器

而TIME_WAIT等待时间是可配置的,可以将时间设置的更短,或者有个套接字选项,叫做地址重用。setsockopt()

3、TCP连接管理中的保活机制:

连接断开有个信息:recv会返回0,send会触发异常

TCP通信中,如果客户端和服务端通信频率并不高,中间突然网断了,没有四次挥手的机会,如果两端通信频率很低,可能需要很久才会发现

在通信中,客户端与服务器若长时间无通信(默认7200s),则TCP服务器会自动的向客户端发送保活探测心跳包,要求对方进行响应(默认每隔75s),若连续多次都没有收到响应(默认9次),则认为连接断开。 这些时间都是可以配置的(如果嫌时间不合理的话)

不是每个连接断开都会有四次挥手

有:正常关机,程序关闭

无:机器断电、突然断网

可靠传输:

面向连接——确保双方都具有数据收发的能力,通过很多特殊机制实现

安全:

丢包检测机制--确认应答机制:接收方要针对收到的每一条数据进行确认回复

丢包重传机制--超时重传机制:等待确认回复超时则重传

有序:

协议字段中的序号&确认序号:进行包序管理,有序交付

校验和字段:校验数据一致性,不一致则丢弃,要求重传

性能的挽回:

TCP为了保护可靠传输,牺牲了传输性能,但是有些性能损失是没有必要的

1、因为发送数据过多,导致对方缓冲区溢出而丢包

1、流量控制:滑动窗口机制

作用:进行流量控制,避免因为发送方发送数据过多导致丢包

关键点:协议字段中的窗口大小 (在6位标志位后面的16位窗口大小)

窗口大小字段:接收方进行数据发送或者确认回复的时候,

告诉对方最多给自己发送多少数据(大小<接收缓冲区空闲空间大小)

滑动窗口机制实现: 通信中套接字会维护一个发送窗口&接收窗口

MSS:最大数据段大小,一个TCP报文的最大数据大小,

通信双方在三次握手阶段会协商MSS大小,取双方较小的一个值

MTU:链路层限制的最大传输单元,以太网默认1500字节

2、因为网络状况的突变,导致大量的丢包 重传

3、因为确认应答丢失所导致的重传

2、停等协议:

发送方发送一条数据后,收到回复才会发送下一条数据

适用于网络状况较差的场景

3、回退N步协议:

滑动窗口机制决定了TCP数据传输可以管线化传输,可以连续发送多个报文,而在传输过程中,如果出现了丢包,回退N步协议,指的是从丢包的这个数据开始重新对数据进行传输

适用于网络状况一般的场景

4、选择重传协议:

传输过程中,丢包了,哪个包丢了,就对哪个包重传

适用于网络较好的场景

5、拥塞控制:

避免因为网络状况突变,因为网络拥塞而导致大量丢包的情况

关键点:进行网络状况的探测

你的电脑已经卡爆了,你还给它塞了很多东西让它接收,丢包的情况不得事丢上加丢?

TCP引入慢启动机制,先发一点数据,探探路,摸清当前的网络情况,速度好了再快增加

刚开始一次传一个包,指数级增长,到达刚开始的这个阈值之后,就开始线性增长,直到出现丢包情况,把阈值进行调整之后(变为窗口的一半),速度就重新降为1,重新开始刚才的过程,不过这次到达阈值之后的线性增长斜率会平缓一些。

拥塞窗口:控制发送数据量的基准

发送数据发小<=min(滑动窗口大小,窗口大小)

拥塞窗口,一般初始值大小为1

拥塞窗口的思想:慢启动,快增长

拥塞窗口从初始值开始进行指数级增长,达到阈值时进行线性增长

6、快速重传协议:

再数据传输过程中,接收方接收数据的时候,并没有接受到起始接收序号的数据,而是接收到了后边的数据(再第一条数据之前先收到了第二条数据,可能前面走的数据还在路上,后面走的先到了)

传统方法——超时重传,接收方不会对后面的数据进行处理,必须要等前面的数据到了才处理后面的数据,接收方就一直慢慢等,直到超时情况出现,给发送方发送一个前面数据的超时重传信号,让把前面的数据重新发一下(效率太低了)

因此,快速重传:接收方为了提高效率,会给发送方回复一个第一条数据的序号确认,接收后续数据的时候都会进行同样的序号确认(收一个后面的数据就给那边说,第一个数据还没莱来呢),发送方在收到三条(三次作为一个基准次数)第一个数据的序号确认之后,则会对第一条数据进行重传。

可靠传输:

1、保证可靠:面向连接、确认应答机制、超时重传机制、序号、确认序号、校验和

2、如何避免丢包?

滑动窗口机制 + 拥塞控制

3、如何进行性能挽回?

快速重传协议:避免每次重传都需要等待超时才进行

延迟发送机制: 解决频繁的小数据发送效率较低的情况,减少了IO次数提高了效率(缓冲区少了就多等等,等发送缓冲区的数据多了再发)

延迟应答机制:基于确认应答机制,接收方需要对发送方的每一条数据进行确认回复。而如果直接对数据进行确认回复,大概率数据在缓冲区并没有被取出,因此这时候的回复会导致窗口大小变小,网络的吞吐率降低了,因此设计者就设计延迟一会应答,这段延迟的时间中,应用程序就有可能将数据取出,保持窗口不变,吞吐率不变,尽可能的总是以最大速率传输数据。

捎带应答机制:接收方再收到发送方发来的数据之后,把接收的确认序号捎带在发送的数据一起发送过去。尽可能减少空报文的传输。

字节流传输:

传输的时候,对数据以字节为单位进行编号,进行传输,不限制传输大小

1、粘包问题:

数据在缓冲区中堆积,将多条数据当作一条数据进行处理的过程

粘包产生的本质原因:是数据之间缺乏边界管理

TCP粘包问题:再传输层,并不管传输的什么数据,只管从缓冲区中取出合适大小

的数据进行操作,没有边界管理。

解决方案:在应用层,程序员对数据进行边界管理

边界管理:明确一条数据从哪儿开始,到哪儿结束

1、特殊字符间隔:需要对数据中的特殊字符进行编码,避免歧义

2、数据定长:数据固定长度,缺陷就是需要以最大长度定线(浪费较多,效率低)

3、数据采用TLV格式:在应用层头部中定义数据的长度(先取头部,根据头部中的长度,决定取多少数据)

TCP粘包了解吗?UDP粘包问题怎么解决?

UDP根本没有粘包问题,因为UDP的面向数据报传输方式,本身就是一次最多交付一条数据(UDP本身就有数据的边界管理)

UDP的sendto接口发送数据,将数据放到发送缓冲区之后,会立即封装头部进行发送。

More translations of反弹in English
ARCore 支持的设备