tcp 序列号

tcp,状态. from异常流程_个人渣记录仅为自己搜索用的博客-优快云博客

转载请注明出处6-TCP6-TCP 协议(序号和确认号)_tcp 最终确认序号_--Allen--的博客-优快云博客6-TCP

接下来的内容是学习后续内容的基础,必须先讲清楚。为了方便你回忆 TCP 首部,这里再次把这个图贴出来,以便对照。


这里写图片描述
图1 TCP 首部

1. 序号

1.1 序号存在的意义

首先得弄清楚为什么要有序号。

在 APUE 基础中,我们通过 TCP 协议将数据发送给对方,就比如 helloworld,这一串字节流,假设被拆分成了三个 TCP 报文段,第一个报文段携带了 hel,第二个报文段携带了 lowo,第三个报文段携带了 rld,这三个报文段不一定是按照顺序送到对端的,那么对端收到这三个段是如何确定他们的顺序的呢?此时序号的意义就体现在这里。

1.2 序号

序号占用 4 字节,即 32 位。它的范围是 [0,232−1]

,也就是说一共有 4 294 967 296 个序号。TCP 协议中的序号,指的是报文段序号。

  • 字节序号

TCP 连接中,为传送的字节流(数据)中的每一个字节按顺序编号。也就是说,在一次 TCP 连接建立的开始,到 TCP 连接的断开,你要传输的所有数据的每一个字节都要编号。这个序号称为字节序号

  • 初始序号 ISN

当新连接建立的时候,第一个字节数据的序号称为 ISN(Initial Sequence Number),即初始序号。ISN 一开始并不一定就是 1。在 RFC (规定网络协议的文档)中规定,ISN 的分配是根据时间来的。当操作系统初始化的时候,有一个全局变量假设为 g_number 被初始化为 1(或 0),然后每隔 4us 加 1. 当 g_number 达到最大值的时候又绕回到 0.当新连接建立时,就把 g_number 的值赋值给 ISN.

在 BSD 系统中,这段代码实现时并未遵守协议,它将 g_number 初始化为 1,每 8us 加 1,也就是说,每隔 1 秒增加 125000,约 9.5 小时后 g_number 又绕回到了 0.

初始序号是非常非常重要的概念,它告诉对端,第一个报文段是谁!而三次握手的目的,就是为了确认初始序号,这个在后面会讲。

  • 报文段序号

如果一个 TCP 报文段的序号为 301,它携带了 100 字节的数据,就表示这 100 个字节的数据的字节序号范围是 [301, 400],该报文段携带的第一个字节序号是 301,最后一个字节序号是 400.


这里写图片描述
图2 前面实验抓取的一个数据包

在图 2 中,报文段序号是 2379453244,它携带了 6 字节的数据 hello\0,这 6 字节的数据字节序号就是从 h->2379453244e->2379453245 一直到最后一个空字符 \0->2379453249.

注意:序号字段只有在下面两种情况的任意一种才有意义:

  • 数据字段至少包含一个字节
  • 这是一个 SYN 段,或者是 FIN 段,或者是 RST 段。

2. 确认号

如果你还记得前面你和你对象发短信的例子的话,这里就不难了。每传送一个 TCP 段,都要等待对方回复一个确认。不过这种方式效率太低,在 TCP 协议中,一般采用累积确认的方式,即每传送多个连续 TCP 段,可以只对最后一个 TCP 段进行确认。

对方通过回复一个确认号,来表示确认已经接收到了哪个 TCP 段。比如发送方发送了一个报文段序号为 301 的 TCP 段,这个段携带了 100 字节数据,则接收方应当回复的确认号是 401,它表示接收方已经收到了字节序号为 [0, 400] 的数据,现在期望你发送字节序号为 401 以及以后的数据。

只有当 ACK 标志位被置位的时候,确认号这个字段才有效。

3. 一次完整的 TCP 连接到释放的过程


这里写图片描述
图3 这个数据包还是前面实验中抓取的

为了能够清晰的看到客户端与服务器的交互过程,这里将它画成了下面的时序图。


这里写图片描述
图4 客户端与服务器的交互

现在,我们只需要观察每一次发送 TCP 段后,对方是如何应答的。为了方便观察序号和确认号,我只保留了后三位。

4. 总结

  • 字节序号与报文段序号
  • 初始序列号
  • 确认号

另外一篇:

理解TCP序列号(Sequence Number)和确认号(Acknowledgment Number)

TCP 序列号TCP 协议中用于标识发送的数据字节流的机制,其作用和工作原理如下: ### 作用 1. **数据排序**:序列号使得接收方能够将接收到的数据按照正确的顺序重组。每个字节都被赋予唯一的编号,从而保证了即使在网络传输过程中数据包乱序到达,也能正确地进行排列[^3]。 2. **可靠传输**:通过确认应答(ACK)机制,发送方可以得知哪些数据已经被对方成功接收,并且在未收到确认的情况下重传相应的数据段。 3. **流量控制与拥塞控制**:序列号也参与了窗口机制,帮助实现流量控制以及网络拥塞状态下的调整。 ### 工作原理 - 每个连接开始时,通信双方都会各自生成一个初始序列号(ISN, Initial Sequence Number),这个值通常是随机化的以增加安全性[^4]。 - 在三次握手建立连接的过程中: - 客户端发送SYN标志位为1的报文给服务器,并携带自己的ISN作为序列号。 - 服务器回应SYN-ACK,即SYN和ACK标志位都置为1;其中ACK是对客户端SYN的确认,序列号则是服务器自己的ISN,而确认号则是客户端ISN加一。 - 客户端再发ACK给服务器完成连接建立,此时它的确认号是服务器ISN加一[^1]。 - 数据传输阶段,每当发送一段数据,序列号就递增该段数据长度对应的字节数。接收方则使用确认号来告知发送方它期望下一次收到的数据起始位置。 - 四次挥手断开连接时,FIN标志位表示结束信号,同样需要通过序列号和确认号来进行可靠的关闭过程。 ```python # 示例:假设有一个简单的数据传输场景 def simulate_sequence_numbers(initial_seq, data_length): # 初始序列号 seq = initial_seq print(f"Initial sequence number: {seq}") # 发送第一个数据段 sent_data_length = data_length print(f"Sent {sent_data_length} bytes, next expected sequence number: {seq + sent_data_length}") # 接收方返回确认号 ack_number = seq + sent_data_length print(f"Acknowledgment number from receiver: {ack_number}") # 模拟运行 simulate_sequence_numbers(1000, 500) ``` 上述代码模拟了一个非常基础的数据传输情况,展示了如何根据发送的数据量更新序列号及生成确认号。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值