TCP的序列号与确认号机制详解
字数 1772 2025-11-25 15:43:14

TCP的序列号与确认号机制详解

描述:TCP的序列号和确认号是TCP可靠传输的核心机制。序列号用于标识每个报文段中数据的字节流位置,确认号用于告知对方已成功接收的数据。理解这两个编号的生成规则和交互逻辑,是掌握TCP可靠性的基础。

详细讲解

  1. 基本概念:字节流编号

    • TCP将应用层交付的数据视为一个无结构的、连续的字节流。
    • 为了管理这个字节流,TCP为每个传输的字节分配一个唯一的序列号(Sequence Number, SEQ)。
    • 序列号是一个32位的无符号整数,取值范围是0到2^32-1(约43亿)。当达到最大值后,会从0开始回绕。
  2. 初始序列号(Initial Sequence Number, ISN)的生成

    • 在一个TCP连接开始时,通信双方需要为自己要发送的数据流选择一个起始序列号,即ISN。
    • 为什么不能固定从0或1开始? 这是出于安全考虑。如果ISN是固定或可预测的,恶意攻击者可能伪造一个具有合法序列号的RST包来重置连接(连接重置攻击)。因此,ISN必须是随机的、不可预测的。
    • 现代操作系统的ISN生成算法:通常基于一个复杂的公式,结合时间戳、散列函数等,确保其随机性和不可预测性。
  3. 三次握手阶段的序列号与确认号交换
    这是理解SEQ和ACK号如何初始化和增长的关键。

    • 第一步(SYN):客户端发送一个SYN报文(标志位SYN=1)。这个报文会指定自己的初始序列号(ISN_c)。由于不携带应用数据,这个报文消耗一个序列号(下次发送数据时,序列号将从ISN_c+1开始)。此时确认号ACK为0。
    • 第二步(SYN-ACK):服务器端回应一个SYN-ACK报文(SYN=1, ACK=1)。这个报文做两件事:
      1. 指定服务器端的初始序列号(ISN_s)
      2. 确认客户端的SYN。确认号(Acknowledgment Number, ACK)的值为 客户端的ISN_c + 1。这个 +1 就是对客户端SYN报文本身的确认(因为SYN标志位消耗一个序列号)。
    • 第三步(ACK):客户端发送一个ACK报文(ACK=1)。这个报文:
      1. 确认服务器的SYN。确认号(ACK)的值为 服务器端的ISN_s + 1
      2. 此时可以开始携带应用数据。数据的第一个字节的序列号就是 ISN_c + 1
  4. 数据传输阶段的序列号与确认号增长规则
    假设连接已建立,客户端序列号为X,服务器端序列号为Y。

    • 规则一:序列号增长。发送方每发送N个字节的数据,其下一个报文的序列号就要增加N。
      • 例:客户端发送一个数据段,序列号SEQ = X,数据长度Len = 100字节。那么,客户端发送的下一个数据段(如果是紧接着的)的序列号将是 X + 100。
    • 规则二:确认号的含义。接收方发送的确认号ACK,表示“我期望收到的下一个字节的序列号”。这隐含了确认号之前的所有字节(即序列号小于ACK的所有字节)都已被成功接收。这种机制称为累计确认
      • 接上例:服务器成功收到客户端发来的100字节数据后,它回复的确认报文中的ACK号应为 X + 100。这个ACK号的含义是:“我已经成功收到了序列号到 X+99 的所有数据,现在我期待你从序列号 X+100 开始发送数据。”
    • 规则三:确认号本身不消耗序列号。纯ACK报文(不携带任何数据)不会导致自己的序列号增长。只有携带数据或SYN/FIN标志的报文才会消耗序列号。
  5. 连接终止(四次挥手)中的序列号与确认号

    • FIN标志位(表示发送方数据已发完)也消耗一个序列号。
    • 假设客户端要关闭连接,其当前序列号为K。
    • 客户端发送FIN报文(FIN=1),其序列号为SEQ = K。
    • 服务器端收到后,回复ACK报文,确认号为ACK = K + 1。
    • 当服务器端也发送FIN报文时,同样遵循上述规则。

总结
TCP的序列号和确认号机制共同构成了可靠传输的基石。序列号确保了数据可按正确顺序重组,确认号则提供了接收情况的反馈。通过“下一个期望的序列号”这种累计确认方式,TCP可以高效地处理数据确认和重传,即使在出现包乱序或丢失的情况下,也能保证数据的完整性和有序性。理解 SEQACK 的“+1”规则(对SYN/FIN的标志位确认)是掌握TCP交互细节的关键。

TCP的序列号与确认号机制详解 描述 :TCP的序列号和确认号是TCP可靠传输的核心机制。序列号用于标识每个报文段中数据的字节流位置,确认号用于告知对方已成功接收的数据。理解这两个编号的生成规则和交互逻辑,是掌握TCP可靠性的基础。 详细讲解 : 基本概念:字节流编号 TCP将应用层交付的数据视为一个无结构的、连续的字节流。 为了管理这个字节流,TCP为每个传输的字节分配一个唯一的序列号(Sequence Number, SEQ)。 序列号是一个32位的无符号整数,取值范围是0到2^32-1(约43亿)。当达到最大值后,会从0开始回绕。 初始序列号(Initial Sequence Number, ISN)的生成 在一个TCP连接开始时,通信双方需要为自己要发送的数据流选择一个起始序列号,即ISN。 为什么不能固定从0或1开始? 这是出于安全考虑。如果ISN是固定或可预测的,恶意攻击者可能伪造一个具有合法序列号的RST包来重置连接(连接重置攻击)。因此,ISN必须是随机的、不可预测的。 现代操作系统的ISN生成算法 :通常基于一个复杂的公式,结合时间戳、散列函数等,确保其随机性和不可预测性。 三次握手阶段的序列号与确认号交换 这是理解SEQ和ACK号如何初始化和增长的关键。 第一步(SYN) :客户端发送一个SYN报文(标志位SYN=1)。这个报文会指定自己的 初始序列号(ISN_ c) 。由于不携带应用数据,这个报文消耗一个序列号(下次发送数据时,序列号将从ISN_ c+1开始)。此时确认号ACK为0。 第二步(SYN-ACK) :服务器端回应一个SYN-ACK报文(SYN=1, ACK=1)。这个报文做两件事: 指定服务器端的 初始序列号(ISN_ s) 。 确认客户端的SYN 。确认号(Acknowledgment Number, ACK)的值为 客户端的ISN_c + 1 。这个 +1 就是对客户端SYN报文本身的确认(因为SYN标志位消耗一个序列号)。 第三步(ACK) :客户端发送一个ACK报文(ACK=1)。这个报文: 确认服务器的SYN 。确认号(ACK)的值为 服务器端的ISN_s + 1 。 此时可以开始携带应用数据。数据的第一个字节的序列号就是 ISN_c + 1 。 数据传输阶段的序列号与确认号增长规则 假设连接已建立,客户端序列号为X,服务器端序列号为Y。 规则一:序列号增长 。发送方每发送N个字节的数据,其下一个报文的序列号就要增加N。 例:客户端发送一个数据段,序列号SEQ = X,数据长度Len = 100字节。那么,客户端发送的下一个数据段(如果是紧接着的)的序列号将是 X + 100。 规则二:确认号的含义 。接收方发送的确认号ACK,表示“我期望收到的下一个字节的序列号”。这隐含了确认号之前的所有字节(即序列号小于ACK的所有字节)都已被成功接收。这种机制称为 累计确认 。 接上例:服务器成功收到客户端发来的100字节数据后,它回复的确认报文中的ACK号应为 X + 100 。这个ACK号的含义是:“我已经成功收到了序列号到 X+99 的所有数据,现在我期待你从序列号 X+100 开始发送数据。” 规则三:确认号本身不消耗序列号 。纯ACK报文(不携带任何数据)不会导致自己的序列号增长。只有携带数据或SYN/FIN标志的报文才会消耗序列号。 连接终止(四次挥手)中的序列号与确认号 FIN标志位(表示发送方数据已发完)也消耗一个序列号。 假设客户端要关闭连接,其当前序列号为K。 客户端发送FIN报文(FIN=1),其序列号为SEQ = K。 服务器端收到后,回复ACK报文,确认号为ACK = K + 1。 当服务器端也发送FIN报文时,同样遵循上述规则。 总结 : TCP的序列号和确认号机制共同构成了可靠传输的基石。序列号确保了数据可按正确顺序重组,确认号则提供了接收情况的反馈。通过“下一个期望的序列号”这种累计确认方式,TCP可以高效地处理数据确认和重传,即使在出现包乱序或丢失的情况下,也能保证数据的完整性和有序性。理解 SEQ 和 ACK 的“+1”规则(对SYN/FIN的标志位确认)是掌握TCP交互细节的关键。