面试官提问:
为什么在 TCP 三次握手的过程中要初始化序列号?为什么不能使用固定的序号,而必须使用随机的初始序列号(ISN)?
应聘者参考回答:
在 TCP 的三次握手过程中,初始化序列号(ISN,Initial Sequence Number)是非常关键的一步,其主要目的与功能如下:
一、为什么要初始化序列号?
- 确保数据传输的有序性
- TCP 是基于字节流的传输协议,发送方每个字节都对应一个序列号;
- 三次握手的过程就是为了让双方同步并确认彼此的初始序列号(ISN);
- 接下来发送的数据段的序列号会在 ISN 的基础上递增,以便接收方进行乱序重组和丢包重传。
- 解决网络中延迟数据包的问题
- 如果一个旧连接的数据包在网络中延迟太久,再次被误收,可能会被当前的新连接识别为有效;
- 为了避免这种“历史包干扰当前连接”的问题,必须确保每次连接的 ISN 足够不同。
二、为什么不能使用固定序列号,而必须使用随机序列号?
- 防止重放攻击与数据混乱
- 若 ISN 是固定的(如每次都是 0),攻击者可以伪造一个数据包,模拟旧连接的状态,导致数据注入攻击;
- 随机化 ISN 可以增强连接的唯一性与安全性,降低被猜测和伪造的风险。
- 满足 TCP 的健壮性设计要求
- RFC 793 和后续规范明确要求 ISN 必须是动态变化的、不可预测的;
- 通常 ISN 由一个 32bit 的计数器生成,每 4ms 递增一次,具有时间敏感性(例如:
ISN = timer * 250
); - 这种设计可以在不同连接之间保证序列号间隔足够,避免误判数据合法性。
三、总结
- 初始化序列号(ISN)是为了可靠、有序地组装数据流;
- 使用随机/递增 ISN 是为了防止历史包干扰与安全攻击;
- 如果序列号可预测,TCP 连接容易遭受伪造或劫持,导致严重的安全问题。
因此,在三次握手中动态初始化序列号是 TCP 协议设计中确保可靠性与安全性的关键策略。
😀 关注 @公众号 程序员陈子青,获取更多 C++ 技术支持。