首页 > 其他分享 >TCP 首部解析与连接的建立与释放

TCP 首部解析与连接的建立与释放

时间:2022-11-03 11:48:27浏览次数:50  
标签:首部 TCP server 发送 ACK client 解析 FIN

1. TCP 首部解析

  • 源端口, 目的端口: 使用 TCP 协议传输数据时, 从本机发送出去时通过的端口和目标机器用于接收的端口
  • 序号(Sequence Number): 用于标记相应的 TCP 报文的第一个字节的一个编号(拆分 TCP 报文发送时, Seq 表示该报文中的数据相对于要发送的所有数据的偏移量)
  • 确认号(Acknowledgement Number): 若 Ack=x, 则表示期望对方下一次发过来的数据的 Seq=x
  • 数据偏移(Data Offset): \(DataOffset = size(TCPHeader) \div 4\)(标识了 TCP 首部的大小). 由数据偏移占4位可知, TCP 首部长度最多 60 个字节
  • 保留位(暂时没有意义)
  • 控制标志(Control Flags):
    • URG: 当该位值为 1 时, 对应的紧急指针有效
    • ACK: 当该位值为 1 时, 表明确认号有效
    • PSH: 当该位值为 1 时, 收到相应报文的主机会尽快将数据交付给相应的程序, 而不会等到缓存满了再向上交付
    • RST: 当该位值为 1 时, 表示网络情况不好, 需要释放连接后, 重新建立连接
    • SYN: 当该位值为 1 时, 表示期望与对方建立连接
    • FIN: 当该位值为 1 时, 表示期望与对方断开连接
  • 窗口大小(Window Size): 用于表示接收/发送窗口的大小
  • 检验和(Check Sum): 通过对 伪首部+首部+数据部分 的计算所得出来的一个检验参照
  • 紧急指针(Urgent Pointer): 设其值为 k, 则表示该 TCP 数据的前 k 个字节是紧急数据
  • 选项(Options)
    • 常见选项之一: 启用 SARQ 协议
    • 常见选项之二: 传递 MSS

2. TCP 的三次握手

  1. 客户端向服务器发送连接建立请求: SYN = 1, Seq = x
  2. 服务器响应客户端的请求, 表示准备好发送数据了: SYN = 1, ACK = 1, Ack = x + 1, Seq = y
  3. 客户端回复服务端的相应, 请求服务端发送数据: ACK = 1, Seq = x + 1, Ack = y + 1

x 和 y 都是是一个随机生成的数字 ISN(Initial Sequence Number)

2.1 为什么需要三次握手, 而不是两次

2.1.1 避免服务器的资源被无端占用

  • 若 client 的第一次建立连接的请求被延迟到与 server 的连接断开后才到 server
  • 会导致 server 单方面地认为自己与 client 建立连接了
  • 这样的情况会使得服务器的资源无端占用

2.1.2 确保 client 与 server 双方都能够发送和接收数据

第二次握手, server 向 client 发送的响应头中包含的关键数据

  • Ack = clientISN + 1: 表示 server 准备好接收来自 client 的请求了

第三次握手, client 向 server 发送的响应头中包含的关键数据

  • Ack = serverISN + 1: 表示 client 可以接收 server 发来的数据了

如果没有第三次握手, 则只能由 client 向 server 发送请求, 而 client 无法接收来自 server 的数据

3. TCP 的四次挥手

  1. client 向 server 发起释放连接的请求(不会主动向 server 发送数据): FIN = 1
  2. server 向 client 返回允许释放连接的响应: ACK = 1
    • 若 server 还有没有发送完的数据, 则不会发送 FIN = 1, 并继续发送数据
    • 若 server 没有需要发送的数据了, 则2, 3步合并, 发送 ACK = 1, FIN = 1
  3. server 数据已经发送完毕, 向 client 发送释放连接的消息: FIN = 1
  4. client 响应 server 的数据: ACK = 1
    • server 收到来自 client 的确认, 立即断开连接
    • client 等待 2MSL 后断开连接(若在这期间收到了来自 server 的信息, 则重新定时)

3.1 为什么 client 必须要等待 2MSL 后才断开连接

3.1.1 保证本次连接所发送的数据不会干扰到下一次的连接

MSL(maximum segment lifetime), 指的是 TCP 报文在网络上的最大生存时间, 一般是 2 分钟, 也可以自己设定. MSL = 2 可以确保当前连接中所传输的内容全部传输完毕

可以想象, 若 client 发送 ACK = 1 后立即断开连接, 而 server 并没有收到该确认消息, 则 server 会继续继续发送 FIN = 1

  • server 可能会重发多次 FIN = 1 的信息, 浪费资源
  • 一个应用程序继承了 client 的同端口, 可能会被 server 发来的信息干扰到

若 client 等待 2MSL 后才断开连接:

  • client 发送的 ACK = 1 的信息 server 并没有收到, 则 server 会继续向 client 重传 FIN = 1 的消息, 而 client 收到 FIN = 1 后, 会重新发出 ACK = 1 的响应, 并重置定时器.
  • 一般来说, FIN = 1 的消息会在 2MSL 内到达 client, 若 FIN = 1 多次重传也没有收到 ACK = 1 的响应, 则其会判断网络拥塞, 自己断开连接

标签:首部,TCP,server,发送,ACK,client,解析,FIN
From: https://www.cnblogs.com/suzukaze/p/TCPHeader_Handshake.html

相关文章