SEQ序号与ACK序号理解总结(一)
Seq:就是我们常说的序号。对于要发送的数据的第一个序号而言这个序号是通过一个算法计算得到一个初始序号(ISN)加1。至于ISN怎么计算而来这里不讨论。这里我们以wireshark序号为准。假设某时序号为1000,简单的理解就是发送方告诉接收端“我发送的数据是从第1000开始的”。
ACK序号:就是我们常说的确认序号。确认序号是上一次已经成功接收到数据字节序号加1。还可以理解为接收端告诉发送端下一次想接收开始序号。假设某时确认序号为1000,简单的理解就是接收方告诉发送方“我已经收到第999序号了,我下一次想接收的数据是从1000开始的”。
首先注意一下3点:
1, 当发送syn标记时将消耗一个序号;
2, 发送fin标记时将消耗一个序号;
3, 数据是每个字节一个序号;
以上知识可以在《tcp/ip详解-卷1》第172页找到。我们根据具体报文来理解这两个概念。Seq序号以下直接简称seq,ack序号以下直接简称ack。
1, 最简单的三次握手
2, 最简单完整数据报文
3, 上面一大堆比较啰嗦。这里只给出这些阶段状态,本文不讨论。
1:syn_send;
2:syn_rcvd;
3:established;
4:established;
5:发送get请求;
6:回复get请求;
7:fin_wait1;
8:close_wait;
9:fin_wait2;
10:last_ack;
11:time_wait;
12:closed。
4, 以上统统总结,就是两句话:
Seq:就是告诉接收方:我发送的数据是从seq开始的。
Ack:就是告诉接收方:我希望下次收到对端发过来的seq序号。
二、现在举例通过seq与ack来分析报文。
1,先看一个最简单的异常报文。注意这里说的异常报文不一定是错误报文。
分析:从seq与ack的序号角度来理解,一点问题都没有,服务器端s成功地接收了发过来的数据。但你可能会疑问:“不是会话建立需要三次握手么?这里没看到三次握手完怎么就发数据了呢”。这里需要理解一点是tcp中ack是一个标记位,与ack序号是两个概念。只有当ack标记位置位时ack序号才有效。看第三个报文,它的ack置位,对服务器来说收到这个报文表示是确认报文,并且确认序号正好是之前发送的seq序号加1。服务器认可这个确认报文,也就接受了发过来数据。
这里还用到一个原则:数据带ack。就是发送数据的同时对上次收到的报文进行确认。这样做是为了减少网络中过多的ack报文,因为ack只是个标记确认用的,单独发送一个确认报文浪费了资源。那你肯定会想“如果没有数据要发送了,那确认报文怎么发送,不发了?”。当然不是这样的,数据带ack只是发送确认报文原则之一。其他发送碰到再讲,这里就不讲了。
2,再来看最常见的一个异常报文——重复确认报文(tcp dup ack)
分析:有重复报文,一般是是丢包或延迟引起的,从这个报文看应该是丢包了。因为接收到告诉发送端想收到的报文序号,发送端立马重传了这个报文。对于wireshark来说,之前收到了ack为9224的报文(17号),现在又收到ack为9224的报文(19号),故wireshark标记为tcp dup ack报文。
3,既然有重复确认,那有没有重复发送的数据呢?答案是当然有。但是不叫重复发送数据,而称为重传报文(tcp Retransmission)
分析:对于wireshark来说收到两次seq为40206的数据报文,就认为这是一个重传的报文。为什么会有重传报文呢?1,丢包;2,延迟。从这个报文上一个报文ack为40206,说明接收端告诉发送端要发送的seq为40206。然后发送了一个seq为40206的报文,然后等待接收端回确认,但等了很久(200ms)还没有收到确认报文,发送端就认为这个包丢包了(注意:只是从发送端的角度来说认为这个包丢包了,到底是丢包还是延迟,不必关心)。这就超时重传的原则。
4, 网络总是存在延迟的,而且可能走不同的路由导致报文产生乱序,这就是乱序报文(out –of- order)。报文乱序wireshark还有一个解析:tcp提前片段(tcp Previous segment no captured)。
分析:对于wireshark来说是根据收到seq去判断是否乱序。乱序一般是因为报文在传输的过程中产生的,但实际上wireshark标记out-of-order只是对于wireshark角度去分析的。实际上这个报文可能是重传报文,需根据实际情况分析。