TCP三次握手

文章目录

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

  1. 第一次握手(客→服)
    SYN=1,seq=x
  • 自己的seq发请求
  1. 第二次握手(服→客)
    SYN=1,ACK=1,seq=y,ack=x+1
  • seq=y:服务端自己的序号
  • ack=x+1:回应客户端刚才的seq
  1. 第三次握手(客→服)
    ACK=1,seq=x+1,ack=y+1
  • seq=x+1:客户端继续用自己的序号
  • ack=y+1:回应服务端的seq

终极总结

  1. SYN、ACK :公共标志位,两端都能发

  2. seq各用各的 ,客户端一套、服务端一套

  3. ack :永远对着对方的seq算,用来告诉对方:我收到你数据了

SYN、ACK的值 一直是0或者1吗,什么时候变化

** 一、SYN 位:只有 0 / 1,只出现在建立连接阶段**

  1. SYN=1
  • 第一次握手:客户端 SYN=1
  • 第二次握手:服务端 SYN=1
    作用:请求同步序列号、发起建连
  1. SYN=0
    连接建立成功后,所有数据报文 SYN 全是 0
    传数据、心跳、断开连接,SYN 一律置 0

SYN 变化时机

  • 建连握手期间:=1
  • 连接建好(ESTABLISHED)之后:永久 =0

ACK 位:也只有 0 / 1

  1. ACK=1
    绝大多数时候都是 1
  • 第二次握手开始
  • 第三次握手
  • 所有传输数据报文
  • 四次挥手所有报文
    只要是应答、正常通信,ACK=1
  1. ACK=0
    极少出现,只在第一次握手
  • 第一次握手:客户端 SYN=1,ACK=0
    这是唯一常见 ACK=0 的场景

ACK 变化时机

  1. 第一次握手:ACK=0
  2. 第二次握手开始往后所有包ACK 永远 =1
    再也不会变回0

** 一句话总结**

  • SYN:只在建连时为1,连上立刻永久变0
  • ACK:只有第一次握手是0,后面全程永久是1

两次握手为什么不行

两次握手只能保证「服务端收到客户端」,保证不了「客户端收到服务端」

假如只用两次握手

  1. 客户端发:SYN 我要连你
  2. 服务端回:SYN+ACK 我同意连你
    到此直接建立连接,结束

出现致命BUG(延迟失效报文问题)

  1. 客户端很早以前发过一个旧的、过期的SYN请求

因为网络卡顿,在路上走了很久才到服务器

  1. 现在客户端早就下线/取消连接了,根本不想连

  2. 这个迟到的旧SYN抵达服务端

  3. 服务端一看:来了连接请求

立刻回复第二次握手报文,直接单方面建立连接

  1. 结果:
  • 客户端:早就忘了这事,完全不收数据
  • 服务端:认认真真开好连接、占着端口、内存、资源,一直死等客户端发数据
  • 大量这种无效空连接堆积,服务器直接卡死、资源耗尽

三次握手怎么解决这个问题?

多出来第三次握手 就是用来验证客户端真的收到回复了

流程补全:

  1. 客→服:我要连你(SYN)

  2. 服→客:我同意连你(SYN+ACK)

  3. 客→服:我收到你的同意了,正式开工

对应上面BUG场景

迟到的旧SYN到服务器:

  1. 服务器回复同意报文发给客户端

  2. 客户端根本没发起新连接 ,不会发第三次确认包

  3. 服务器收不到第三次握手,直接放弃这次连接,不建立

  4. 完美杜绝无效空连接,不浪费任何资源

极简总结

  1. 两次握手无法确认客户端是否收到服务端报文

  2. 网络延迟会产生过期SYN报文

  3. 导致服务端单方面建立大量无效连接 ,浪费端口与内存

  4. 第三次握手确认双方收发能力全部正常,过滤无效请求

服务器收不到第三次握手,放弃这次连接的时间间隔是多少

服务器发完 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的全称是什么

  1. SYN
    Synchronize

    中文:同步

    作用:同步初始序列号,发起建连

  2. ACK
    Acknowledgment

    中文:确认、应答

    作用:确认收到对方报文

  3. seq
    Sequence Number

    中文:序列号

    自己发数据的顺序编号,本机独有

  4. ack
    Acknowledgment Number

    中文:确认号

    用来回应对方,值 = 对方seq + 1

** 速记**

  • SYN=同步
  • ACK=确认
  • seq=自己的发送序号
  • ack=回应对方的确认序号
相关推荐
liulilittle1 小时前
TCP BBR调优及监控
linux·网络·网络协议·tcp/ip·win
凯瑟琳.奥古斯特1 小时前
IP组播跨子网传输核心技术解析
java·开发语言·网络·网络协议·职场和发展
仍然.1 小时前
HTTPS
网络协议·http·https
handler011 小时前
TCP(传输控制协议)核心机制与底层原理
linux·网络·c++·笔记·网络协议·tcp/ip·操作系统
龙侠九重天2 小时前
大模型流式输出实战:SSE 与 WebSocket
网络·websocket·网络协议
weixin_530152602 小时前
【干货】SFP连接器选型指南:数据速率、光导配置与散热设计 | VOOHU 沃虎电子
网络协议·信息与通信
蚊子码农3 小时前
每日一题--TR-069协议基础了解
网络协议
H Journey3 小时前
TCP断开连接四次挥手
网络·tcp/ip·四次挥手
江上清风山间明月3 小时前
RPC failed; curl 65 OpenSSL SSL_read: OpenSSL/3.1.2错误解决方法
网络协议·rpc·ssl·failed