UDP / TCP 协议

目录

UDP协议

TCP协议

TCP的特点

TCP的核心机制

核心机制一:确认应答(可靠机制)

核心机制二:超时重传(可靠机制)

核心机制三:连接管理(可靠机制)

TCP三次握手

TCP四次挥手


UDP协议

UDP协议的报文格式:

16位UDP长度,表示整个数据报(UDP首部+UDP数据)的最大长度。UDP报文长度占两个字节,16位表示的数据范围(0-65535)也就是64kb,UDP数据报最大长度就是64kb。

校验和:因为网络传输中,由于一些外部干扰,数据传输可能会出现出错的情况,网络传输主要是光信号和电信号,由于电磁场、高能离子等,就可能出现比特翻转。因此就需要能识别出出错的数据,所以就有了校验和。

校验和本质上其实也是一个字符串,是通过原始数据生成的体积比原始数据更小,原始数据相同得到的校验和就一定相同,反之,校验和相同那么原始数据大概率也是相同的(不相同的概率忽略不计)。

数据发送之前,先把整个数据包的数据都代入计算一个校验和,把数据和校验和一起发送给对端。接收方收到之后重新计算一下校验和,和收到的校验和进行对比(UDP发现校验和不一致,就会直接丢弃)

UDP的特点:

**无连接:**UDP协议本身不会存储对端的信息,发送数据的时候要显示指定对端的IP和端口号,不需要建立连接。

**不可靠传输:**没有任何安全机制,发送端发送数据报以后,如果因为网络故障该段无法发到对方,UDP协议层也不会给应用层返回任何错误信息。

**面向数据报:**应用层交给UDP多长的报文,UDP原样发送,既不会拆分,也不会合并。

**全双工:**UDP的socket既能读也能写。

大小受限:UDP协议首部中有一个16位的最大长度。也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部)

缓冲区:UDP没有真正意义上的 发送缓冲区。发送的数据会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作;UDP具有接收缓冲区,但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致;如果缓冲区满了,再到达的UDP数据就会被丢弃。

TCP协议

TCP的结构:

源端口号和目的端口号就是说数据从哪里来到哪里去。

4位首部长度:TCP报头的长度是不固定的报头最短是20字节(没有选项),报头最长是60字节(选项最多是40字节)。

4 bit 范围是 0-15,而是使用的是 "4字节为单位",不是使用字节为单位。所以,固定部分是20,选项部分最多是40

校验和:和UDP协议一样。

保留位:因为UDP的长度是64kb,我们无法改变,所以发明TCP的人做出了改变,加入了保留位,先占个位置,如果后面需要就可以进行扩展使用。

TCP的特点

1.有连接:发送方和接收方会保留对方的信息(如果A和B建立连接,B拒绝了,就无法建立连接,通信就无法完成)

2.可靠传输:A给B发消息,消息有没有成功送达A可以感知到(如果发送失败就可以进行采取一定的措施)

3.面向字节流:TCP的传输和文件操作一样都是以字节为单位的

4.全双工:一个通道允许双向通信就是全双工反之就是半双工(一个socket对象既可以发送数据也能接收数据)

TCP的核心就是可靠传输

TCP的核心机制

TCP如何保证可靠传输:

核心机制一:确认应答(可靠机制)

发送方把数据发送给接收方后,接收方收到数据之后就会给发送方返回一个应答报文(acknowledge 简称 ack),发送方收到应答报文后就知道自己的数据发送成功了。

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

引入序号之后,接收方就可以根据序号对数据进行排序

TCP在接收方会安排 "接收缓冲区"(内存,操作系统内核里)通过网卡读到的数据,先放到接收缓冲区中,后续代码里调用 read,也是从接受缓冲区来读的

缓冲区根据序号来排序,序号小的在前面,大的在后面,确保前面的数据已经到了,然后read才能接触阻塞,如果是后面的数据先到,read继续阻塞,不会读取到数据

如何确认一个数据包是普通数据还是ack数据呢?

上面的TCP结构图中ACK为1,就表示当前数据包是一个应答报文,此时该数据包中的确认序号字段才能生效,如果这一位为0,则表示当前数据包是一个普通报文,此时该数据包中的确认序号字段不会生效。

通过特殊的ack数据包里携带的确认序号告诉发送方哪些数据已经被收到了,此时发送方就知道自己刚刚发送的数据是否成功。TCP的初心就是可靠传输,达成可靠传输的核心机制是确认应答

核心机制二:超时重传(可靠机制)

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

确认应答是一个比较理想的情况,如果网络传输过程中,出现了丢包该怎么办?

首先我们要知道丢包的原因:

如果我们把网络想象成错综复杂的公路,在公路上就会有很多收费站,正常情况如果车流量不大,车辆都能正常通过,但是如果节假日就会发生堵车的情况,这种情况车辆就没办法正常通过。在网络中我们可以把收费站理解成 "路由器/交换机" 如果数据包太多,就会在路由器/交换机中出现 "堵车" 的情况,但是路由器/交换机针对 "堵车" 的情况是比较粗暴的,它会把数据包直接丢掉,此时这个数据包就在网络上消失了。这也就是我们所说的丢包。

丢包是一个随机事件,因此在TCP传输过程中存在两种情况:

无论是哪一种情况,A都会重新传输,如果丢包的概率是10%,再重传一次,两次都丢包的概率就是1%,传输成功的概率是很大的,重传操作大幅度提升了数据传输成功率。

那么发送方何时进行重传呢?

发送方,发出数据后,会等待一段时间,如果这个时间内没有收到ack就会触发重传。

初始的等待时间是可以配置的,也可以动态变化,每经历一次超时重传,下次的等待时间就会变长。但是也不是无限变长,超时重传次数达到一定程度/等待时间达到一定程度就认为网络出现严重故障,放弃这一次传输

如果传输的时候ack丢了,触发了超时重传,那么接收方收到了两条一样的数据这样会不会给带来bug呢?

TCP有一个接收缓冲区(一个内存空间)会保留已经收到的数据和数据的序号,接收方如果发现,当前发送方发来的数据是已经在接收缓冲区中,接收方就会直接把这个后来的的数据丢弃掉,以确保读的时候只读到一条数据。

接收缓冲区不仅可以去重,还能进行排序,确保发送的顺序。

确认应答和超时重传,是TCP协议中最核心的两个机制,保证了TCP能够进行可靠传输

问:保证TCP可靠传输的关键机制是三次握手吗

答:不是,是 确认应答﹢超时重传,三次握手的可靠性也是要靠确认应答和超时重传的

核心机制三:连接管理(可靠机制)

连接管理:建立连接(TCP三次握手)+ 断开连接(TCP四次挥手)

TCP三次握手

TCP在连接过程中,通信双方一共需要 "打三次招呼" 才能建立连接。

握手(handshake),握手操作指的是没有实际的业务,只是"打个招呼"。发送一个不携带业务的数据,通过这个数据和对方 "打个招呼"


HTTPS,获取证书,验证证书,加密对称密钥,传输对称密钥,确认对称密钥收到等,这些就是SSL协议的 "握手流程"

三次握手时服务器和客户端的状态:

closed:不存在的状态,tcp 还没有连接

listen:服务器启动,随时可以有客户端连上来(new ServerSocket的时候,就会进入 listen 状态)

syn_sent / syn_rcvo:这两个状态的存在时间非常短,正常情况下是看不动这两个状态的

eatablished:连接建立完毕,随时可以发送数据

问:为什么要握手三次,握两次或四次行不行?

答:握四次没必要,握两次不足以完成验证发送方和接收方的接收能力和发送能力。

第一次握手后,服务器(B)知道了自己可以成功接收数据,客户端(A)可以成功发送数据,但 A 不知道;第二次握手后,A知道自己可以成功发送数据和接收数据,但是B只知道自己可以成功接收数据,并不知道自己是否可以成功发送数据;第三次握手后,B就知道自己成功发送了数据。此时握手完成,此时A和B记录了对方的信息

三次握手的核心作用:

  1. 确认当前网络是否通畅

  2. 让发送方和接收方都知道知道的接收能力和发送能力是否正常

  3. 让双方在握手过程中针对一些重要的参数进行协商

TCP四次挥手

断开连接(客户端和服务器都可以发起)

TCP四次挥手可以把中间的两次合二为一吗?

不一定

不能合并的原因是ack和第二个fin触发的时机不同,ack是内核响应的(B收到fin会立即返回ack),而第二个fin是应用程序的代码触发的,从服务器收到fin(同时返回ack)再到执行到发起fin的代码,这中间要经历的时间是不确定的。

TCP三次握手的ack和第二个syn都是内核触发的,同一时机,所以可以合并。
三次握手,一定是客户端主动发起syn (第一次握手,一定是客户端开头的)

四次挥手,客户端和服务器,都可以主动发起FIN(就看是谁先调用close),但是实际情况下,还是客户端断开连接的可能性更大

四次挥手时服务器和客户端的状态:

TIME_WAIT:主动发起FIN的一方,就会进入到TIME_WAIT

CLOSE_WAIT:被动发起FIN的一方,就会进入CLOSE_WAIT

进入CLOSE_WAIT 状态时,服务器正在等待应用程序代码调用close方法。

CLOSE_WAIT 正常开发中,应该是看不到的。原则上来说,感知到对方断开之后,就应该尽快的执行close ,如果发现服务器存在大量的 CLOSE_WAIT,而且持续时间很长,此时意味着代码大概率有bug(检查是否执行到close了)

TIME_WAIT:连接终止时主动关闭方进入的等待状态,持续时间为2MSL(假设网络上任意两个节点通信消耗的最大时间为MSL,TIME_WAIT等待的时间就是2MSL)

假设出现这样的情况:如果B给A发FIN,A收到之后,返回ACK就把连接释放了,但此时这个ACK丢包了,B就会重传FIN,此时就无人来处理重传的FIN了


所以 A 这边 FIN 之后不能立即释放连接,而是要等一下,等对方是否可能会重传FIN(最后一个ACK是可能丢包的),多等一会,确认确实对方不会重传FIN再释放

相关推荐
liebe1*12 小时前
第十三章 网络服务和应用
网络协议·tcp/ip
qq_254674412 小时前
SSL/TLS
网络协议·github·ssl
普普通通的南瓜2 小时前
SM2 vs RSA/ECC:双算法 SSL 证书的性能对比与优化方案
数据库·网络协议·ssl
jenchoi4138 小时前
【2025-11-07】软件供应链安全日报:最新漏洞预警与投毒预警情报汇总
网络·安全·web安全·网络安全
防火墙在线11 小时前
前后端通信加解密(Web Crypto API )
前端·vue.js·网络协议·node.js·express
9527华安12 小时前
FPGA纯verilog实现 2.5G UDP协议栈,基于1G/2.5G Ethernet PCS/PMA or SGMII,提供14套工程源码和技术支持
5g·fpga开发·udp·ethernet·verilog·sgmii·2.5g udp
-dcr13 小时前
37.华为云网络类云服务
网络·vpn·vpc·elb·对等连接
东方隐侠安全团队-千里13 小时前
第4节 ARPANet 第一次意识到“密码不能明着传”
网络·安全·web安全
FreeBuf_13 小时前
QNAP紧急修复Pwn2Own 2025比赛中遭利用的7个0Day漏洞
网络·安全·web安全