zoukankan      html  css  js  c++  java
  • TCP三次握四次挥手里seq和ack号的【正确】理解

    1 理论知识

    先上一张图,TCP/IP详解第18章的这张图描述了一个正常的三次握手和四次挥手的状态迁移,以及seq、ack序号的变化。

    基本状态看图就能了解,本文主要围绕序号的变化进行讲解。

    clipboard

    1)seq序号

    seq的初始值在不同系统实现不一样,一般为随时间增长的值。当seq超过4字节存储空间后从0开始。

    在某个方向上传输N个字节的数据,序列号就+N,因此seq用于确认在某个方向上传输的字节数。

    如果传输的数据字节为0,即只有首部,那序列号还增加吗?当syn 或 fin被置1,虽然报文里长度为0,计算ACK时我们可以认为其长度为1。其他情况(如只有ack)不增加。

    2)ack序列号

    只有ack标志置1才有效。在TCP交互的整个周期,除了syn包外其他所有包ack都被置1。

    ack序列号是上个报文的序列号+已经成功收到数据长度,比如上次成功接收了seq为1,长度为1000的数据,发送的ack序号为1001,表示我seq1000以前的数据我已经成功接收了,我对序列号1001开始的数据感兴趣。

    2 实例

    clipboard

    这是一次http交互的一个例子。①~③为三次握手,④~⑥为数据传送阶段,⑦~⑨为四次挥手过程(这里实际只有三个包,因为⑧结合了fin和ack两个步骤)。

    我们看第一个包的seq和ack都是0,这是wireshark为了方便阅读将序号重0开始计算(没有改变实际值),我们看到有字段里有两个带RAW的字段,它们才是序号真实的值。

    注:

    1)在下面的解析中,我们不会使用raw的值,但为了说明不是从0开始,我们取整数10000和20000作为两端seq的初始值。

    2)192.168.31.21记为A,211.158.235.30记为B。

    2.1 三次握手过程

    序号变化(假设从10000和20000作为初始值):

    image

    首先A向B发一个SYN包,告诉B请求建立连接。seq为初始化的随机值(如何初始化和系统具体实现有关),这里假设为10000,此时ACK序号为0。

    B收到后会发一个对SYN包的确认包(SYN+ACK)回去,表示对第一个SYN包的确认,并继续握手操作。

    此时B也以一个随机值来初始化seq(与A无关),这里假设为20000。B的ACK是A的seq加1,即10000+1=10001。表示你的请求我已收到,我这方的序号就从20000开始,由于你的syn包消耗了1字节,我期望下一个收到的序列号从10001开始。

    A收到SYN+ACK 包后回一个确认包(ACK)通知B连接已建立。

    它的seq是上个请求(①)的seq加1,即10000+1=10001,当然也等于上一个包(②)的ACK,ACK是B的seq加1,即20000+1=20001,用于确认收到②(syn被置位,所以也消耗了1字节)。

    至此,三次握手完成,一个TCP连接建立完成。

    2.2 数据传输阶段

    image

    ④ A发起Get请求,由于上一个③的len=0,且没有syn或fin标志,因此没有消耗seq的值,seq不变还是10001。ACK序号确认的还是上一个收到的②(这段期间也没有收到新的包)。

    ⑤ B对收到的④发出回应,告诉A我已经收到。由于上一个请求②消耗了1字节,这里seq为20001。ACK为④的seq+len=10001+183=10184。

    ⑥ B发送200ok,由于⑤长度为0没有消耗seq,这里seq仍然为20001,ACK序号确认的还是上一个收到的④。

    2.3 四次挥手

    计算过程基本相同,几个注意点是:

    1)A对⑥的确认合并到第一个挥手包里了。

    2)⑧将FIN和ACK原本的两次挥手合并。

    image

    ⑦ 确认⑥,并发出挥手。

    ⑧ 确认⑦,并发出挥手。⑦长度0,但是有FIN标志,消耗1字节,ACK=10184+1=10185。

    ⑨ 确认⑧,虽然⑧长度为0,但是有FIN标志,消耗1字节,ACK=20155+1=20156。至此挥手完成,TCP整个生命周期结束。

  • 相关阅读:
    cs231n --- 3 : Convolutional Neural Networks (CNNs / ConvNets)
    cs231n --- 1:线性svm与softmax
    Python的下划线_
    Python的类(class)
    python self
    MFC中应用对象的成员:窗口指针m_pMainWnd说明
    MSTP+VRRP组合组网
    VRRP组网下同网段内配置基于全局地址池的DHCP服务器
    路由器/交换机Console口登录密码丢失后如何恢复
    交换机处于同一网络作为DHCP中继与服务器
  • 原文地址:https://www.cnblogs.com/realjimmy/p/12930797.html
Copyright © 2011-2022 走看看