TCP三次握手

5 阅读3分钟

TCP三次握手

  • 它是TCP协议建议可靠连接的核心机制,通过三次交互确认双方的发送和接收能力正常,同步序列号和确认号,为后续的可靠数据传输打下基础
  • 是面向连接、可靠的传输层协议,在客户端和服务端传输数据前,必须先通过三次握手建立双向的连接通道,本质是解决网络不可靠带来的连接确认问题

三次握手的完整过程(带核心标志位/序列号)

  • TCP报文的核心标志位:SYN(同步连接、发送同步请求)、ACK(确认收到报文);核心序号:seq(发送序列号)、ack(确认序列号,代表期望收到的下一个字节序列号)

1. 第一次握手:客户端 ---> 服务器(发起连接)

  • 客户端想服务端发送SYN报文,标志位SYN=1,随机生成一个初始序列号seq=x(x为随机32位整数)
  • 客户端进入SYN-SENT(同步已发送)状态,等待服务器确认
  • 目的:告诉服务器我想和你建立连接,我的初始化发送序列号是x,你能收到我的消息么

2. 第二次握手:服务器-->客户端(确认连接 + 同步自身)

  • 服务器收到客户端的SYN保温后,验证通过则返回SYN + ACK报文
    • 标志位SYN=1 + ACK=1(同时发起自身同步、确认客户端的请求)
    • 确认号ACK=x+1(告诉客户端我收到了你的seq=x的报文,下次请求发(x+1)
    • 随机生成自身的初始化序列号seq=y(y为另一随机32位整数)
  • 服务器进入SYN-RCVD(同步已接收)状态,等待客户端最终确认
  • 目的:告诉客户端我能收到你的消息,我的初始发送序列号是y,你能收到我的消息么

3. 客户端--->服务器(最终确认)

  • 客户端收到服务器的SYN+ACK报文后,返回ACK报文
    • 标志位ACK=1
    • 确认号ACK=y+1(告诉服务器我收到了的seq=y的报文,下次请发y+1)
    • 序列号seq=x+1(遵循之前的约定,从x+1开始发送),客户端发送完成后进入ESTABLISHED(连接已建立)状态,服务器收到ACK报文后,也进入ESTABISHED状态,目的:告诉服务器我能收到你的消息,连接正式建立,我们可以传输数据了
客户端                服务器
  |                    |
  |  SYN(seq=x)        |
  |  →→→→→→→→→→→→→→→→→|  第一次握手
  |                    |  进入SYN-RCVD
  |  ACK(ack=x+1)      |
  |  SYN(seq=y)        |
  |  ←←←←←←←←←←←←←←←←←|  第二次握手
  | 进入SYN-SENT       |
  |  ACK(ack=y+1)      |
  |  seq=x+1           |
  |  →→→→→→→→→→→→→→→→→|  第三次握手
  | 进入ESTABLISHED    |  进入ESTABLISHED
  |                    |
  |===== 开始传数据 =====|

为什么必须是三次,不是两次/四次

  • 核心原因:确认双方的发送能力和接收能力都正常,且同步双方的初始序列号,这是TCP可靠传输的前提,两次握手无法实现,四次握手则多余
  • 三次握手的本质:一次单项能力确认(客->服)+一次双向能力确认(服-》客) + 一次最终确认(客->服),刚号完成双向连接的校验

三次握手的常见异常场景

  • 客户端SYN报文丢失:客户端超时重传SYN报文(默认重传次数有限,超过则连接失败)
  • 服务器SYN+ACK报文丢失:客户端超时重传,服务器若多次收到重复SYN,会返回重复的SYN+ACK,且不会重复建立连接
  • 客户端第三次ACK报文丢失:服务器进入SYN-RCVD状态后超时,会重传SYN+ACK;若服务器超时前收到客户端的后续数据,会默认ACK已到达,直接建立连接
  • SYN洪泛攻击:攻击者发送大量伪造的SYN报文,使服务器处于SYN-RCVD状态,耗尽服务器连接资源,导致正常请求无法建立连接(防御手段:SYN Cookie、限制SYN重传次数等)