文章目录
- TCP三次握手
-
- 一、核心前提
- 二、三次握手详细流程(规范表述)
- 三、关键总结(必看重点)
- 四、疑问处理
-
- [SYN、ACK的值 一直是0或者1吗,什么时候变化](#SYN、ACK的值 一直是0或者1吗,什么时候变化)
- 两次握手为什么不行
- 服务器收不到第三次握手,放弃这次连接的时间间隔是多少
- SYN、ACK、seq、ack的全称是什么
TCP三次握手
TCP(传输控制协议)是面向连接、可靠的传输层协议,"三次握手"是TCP建立连接的核心流程,目的是确认通信双方的发送和接收能力,同步连接参数(如序列号),为后续可靠数据传输奠定基础。
一、核心前提
TCP连接建立需两个主体:客户端 (主动发起连接方)和服务器(被动接受连接方)。双方需通过三次交互,互相确认"我能发、我能收,且知道你能发也能收"。
二、三次握手详细流程(规范表述)
注:核心标识说明------SYN(同步位,用于发起连接、同步序列号);ACK(确认位,用于确认收到数据);seq(序列号,标识发送数据的顺序);ack(确认号,告知对方"我已收到你到seq=N的数据,下次请发seq=N+1")。
服务器 客户端 服务器 客户端 第一次握手:SYN=1,seq=x,ACK=0(发起连接请求) 进入SYN-SENT状态 第二次握手:SYN=1,seq=y,ACK=1,ack=x+1(确认并回应) 进入SYN-RCVD状态 第三次握手:ACK=1,seq=x+1,ack=y+1,SYN=0(最终确认) 进入ESTABLISHED状态 进入ESTABLISHED状态,连接建立
第一次握手:客户端发起连接请求
客户端主动向服务器发送连接请求报文,报文特征:SYN=1(表示发起同步),seq=x(x为客户端随机生成的初始序列号,用于标记后续发送的数据顺序),ACK=0(此时未确认任何数据)。
目的:告知服务器"我想和你建立连接,我的初始序列号是x,请你确认"。此时客户端进入"SYN-SENT"状态(等待服务器响应)。
第二次握手:服务器确认并回应
服务器收到客户端的SYN报文后,确认客户端的发送能力正常,随即向客户端发送响应报文,报文特征:SYN=1(服务器也发起同步,告知客户端自己的发送能力),seq=y(y为服务器随机生成的初始序列号),ACK=1(确认收到客户端报文),ack=x+1(确认客户端的seq=x已收到,下次客户端需发送seq=x+1)。
目的:告知客户端"我已收到你的连接请求,我也能向你发送数据,我的初始序列号是y,请你确认我的接收能力"。此时服务器进入"SYN-RCVD"状态(等待客户端最终确认)。
第三次握手:客户端最终确认
客户端收到服务器的SYN+ACK报文后,确认服务器的发送和接收能力均正常,向服务器发送最终确认报文,报文特征:ACK=1(确认收到服务器报文),seq=x+1(遵循服务器的ack要求,后续数据从x+1开始),ack=y+1(确认服务器的seq=y已收到,下次服务器需发送seq=y+1),SYN=0(无需再发起同步)。
目的:告知服务器"我已确认你的能力,连接可以正式建立,我们可以开始传输数据了"。此时客户端进入"ESTABLISHED"(连接建立)状态;服务器收到该报文后,也进入"ESTABLISHED"状态,三次握手完成。
三、关键总结(必看重点)
- 三次握手的核心是"双向确认":客户端确认服务器能收能发,服务器确认客户端能收能发,缺一不可。
- 为何需要三次?两次握手仅能确认"客户端能发、服务器能收",无法确认"服务器能发、客户端能收",会导致连接不可靠;三次握手可完整完成双向确认。
- 核心原则:每次交互均需确认对方的序列号,确保后续数据传输时,双方能准确识别数据顺序、避免丢失或乱序。
至此,TCP三次握手流程结束,双方进入连接建立状态,可开始进行可靠的数据传输。
四、疑问处理
SYN、ACK,seq,ack这些客户端和服务端是共有的吗
1. 标志位 SYN、ACK:全局共有,客户端、服务端都能用
- SYN:谁发起建连谁发,两端都可携带
- ACK:确认报文专用,所有回复包基本都带
- 只是作用场景不同,不是专属某一端
2. 序列号 seq:各自私有,互不共用
- 客户端有自己的客户端seq
- 服务端有自己的服务端seq
- 双方独立生成,互不干涉
3. 确认号 ack:由对方seq推导出来,用来回应对方
公式固定:
ack = 对方发来的seq + 1 \text{ack} = \text{对方发来的seq} + 1 ack=对方发来的seq+1
一眼看懂
设:
客户端初始序号:C_seq = x
服务端初始序号:S_seq = y
- 第一次握手(客→服)
SYN=1,seq=x
- 用自己的seq发请求
- 第二次握手(服→客)
SYN=1,ACK=1,seq=y,ack=x+1
- seq=y:服务端自己的序号
- ack=x+1:回应客户端刚才的seq
- 第三次握手(客→服)
ACK=1,seq=x+1,ack=y+1
- seq=x+1:客户端继续用自己的序号
- ack=y+1:回应服务端的seq
终极总结
-
SYN、ACK :公共标志位,两端都能发
-
seq :各用各的 ,客户端一套、服务端一套
-
ack :永远对着对方的seq算,用来告诉对方:我收到你数据了
SYN、ACK的值 一直是0或者1吗,什么时候变化
** 一、SYN 位:只有 0 / 1,只出现在建立连接阶段**
- SYN=1
- 第一次握手:客户端 SYN=1
- 第二次握手:服务端 SYN=1
作用:请求同步序列号、发起建连
- SYN=0
连接建立成功后,所有数据报文 SYN 全是 0
传数据、心跳、断开连接,SYN 一律置 0
SYN 变化时机
- 建连握手期间:=1
- 连接建好(ESTABLISHED)之后:永久 =0
ACK 位:也只有 0 / 1
- ACK=1
绝大多数时候都是 1
- 第二次握手开始
- 第三次握手
- 所有传输数据报文
- 四次挥手所有报文
只要是应答、正常通信,ACK=1
- ACK=0
极少出现,只在第一次握手
- 第一次握手:客户端 SYN=1,ACK=0
这是唯一常见 ACK=0 的场景
ACK 变化时机
- 第一次握手:ACK=0
- 从第二次握手开始往后所有包 :ACK 永远 =1
再也不会变回0
** 一句话总结**
- SYN:只在建连时为1,连上立刻永久变0
- ACK:只有第一次握手是0,后面全程永久是1
两次握手为什么不行
两次握手只能保证「服务端收到客户端」,保证不了「客户端收到服务端」
假如只用两次握手
- 客户端发:SYN 我要连你
- 服务端回:SYN+ACK 我同意连你
到此直接建立连接,结束
出现致命BUG(延迟失效报文问题)
- 客户端很早以前发过一个旧的、过期的SYN请求
因为网络卡顿,在路上走了很久才到服务器
-
现在客户端早就下线/取消连接了,根本不想连
-
这个迟到的旧SYN抵达服务端
-
服务端一看:来了连接请求
立刻回复第二次握手报文,直接单方面建立连接
- 结果:
- 客户端:早就忘了这事,完全不收数据
- 服务端:认认真真开好连接、占着端口、内存、资源,一直死等客户端发数据
- 大量这种无效空连接堆积,服务器直接卡死、资源耗尽
三次握手怎么解决这个问题?
多出来第三次握手 就是用来验证客户端真的收到回复了
流程补全:
-
客→服:我要连你(SYN)
-
服→客:我同意连你(SYN+ACK)
-
客→服:我收到你的同意了,正式开工
对应上面BUG场景
迟到的旧SYN到服务器:
-
服务器回复同意报文发给客户端
-
但客户端根本没发起新连接 ,不会发第三次确认包
-
服务器收不到第三次握手,直接放弃这次连接,不建立
-
完美杜绝无效空连接,不浪费任何资源
极简总结
-
两次握手无法确认客户端是否收到服务端报文
-
网络延迟会产生过期SYN报文
-
导致服务端单方面建立大量无效连接 ,浪费端口与内存
-
第三次握手确认双方收发能力全部正常,过滤无效请求
服务器收不到第三次握手,放弃这次连接的时间间隔是多少
服务器发完 SYN+ACK(第二次握手)后,收不到客户端的 ACK(第三次握手),不会立刻丢,而是会「重传几次 + 等待一段指数退避的时间」,最后才放弃。
下面按 Linux 默认配置说(最常见):
1. 控制参数
服务器侧:
net.ipv4.tcp_synack_retries = 5 # 默认5次
含义:发 SYN+ACK 后,最多重传 5 次,仍无第三次握手,就丢弃连接、释放资源。
*2. 每次等待多久(指数退避)
初始超时 1s,后面每次翻倍:
- 第 1 次重传:等 1s 没收到 → 重发
- 第 2 次重传:再等 2s 没收到 → 重发
- 第 3 次重传:再等 4s → 重发
- 第 4 次重传:再等 8s → 重发
- 第 5 次重传:再等 16s → 重发
- 最后一次重发后再等 32s → 彻底放弃
总时间:
$ 1 + 2 + 4 + 8 + 16 + 32 = 63 秒 1+2+4+8+16+32 = 63\text{ 秒} 1+2+4+8+16+32=63 秒
也就是说:
默认情况下,服务器大概等 1 分钟左右(63s)还没第三次握手,就扔掉这个半开连接。
3. 和"两次握手为什么不行"的关系
- 两次握手:服务器直接进入连接状态,永久占着资源等数据
- 三次握手:服务器只在 63s + 有限次重传 内等第三次 ACK;超时没收到 → 自动放弃、释放端口和内存
所以:
- 两次握手:资源永远泄漏
- 三次握手:最多等一分钟,超时自动清理,不怕迟到的旧 SYN
**4. 一句话总结
默认 5 次重传,间隔 1/2/4/8/16/32 秒,合计 63 秒,没第三次握手就丢弃连接。
SYN、ACK、seq、ack的全称是什么
-
SYN
Synchronize中文:同步
作用:同步初始序列号,发起建连
-
ACK
Acknowledgment中文:确认、应答
作用:确认收到对方报文
-
seq
Sequence Number中文:序列号
自己发数据的顺序编号,本机独有
-
ack
Acknowledgment Number中文:确认号
用来回应对方,值 = 对方seq + 1
** 速记**
- SYN=同步
- ACK=确认
- seq=自己的发送序号
- ack=回应对方的确认序号