1 理论知识

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

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

1)seq序号

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

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

如果传输的数据字节为0,即只有首部,那序列号还加吗?当syn 或 fin被置1,序列号也会+1。其他情况(如只有ack)不加。

2)ack序列号

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

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

2 实例

这是一次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作为初始值):

① 首先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 数据传输阶段

④ 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.2 四次挥手

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

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

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

⑦ 确认⑥,并发出挥手。

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

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

TCP三次握手的seq和ack号的【正确】理解的更多相关文章

  1. TCP 三次握手四次挥手, ack 报文的大小.tcp和udp的不同之处、tcp如何保证可靠的、tcp滑动窗口解释

    一.TCP三次握手和四次挥手,ACK报文的大小 首先连接需要三次握手,释放连接需要四次挥手 然后看一下连接的具体请求: [注意]中断连接端可以是Client端,也可以是Server端. [注意] 在T ...

  2. TCP:三次握手,URG、ACK、PSH、RST、SYN、FIN 含义

    http://blog.csdn.net/wudiyi815/article/details/8505726 TCP:SYN ACK FIN RST PSH URG简析   三次握手Three-way ...

  3. TCP三次握手中SYN,ACK,seq ack的含义

    转至:https://www.cnblogs.com/muyi23333/articles/13841268.html 1.TCP 为什么三次握手而不是两次握手 1.防止已失效的连接请求又传送到服务器 ...

  4. TCP 三次握手和四次挥手中的ACK 为什么总是SYN + 1 或者 FIN +1 而不是+ 其他数值?

    TCP 三次握手的时候 1.客户端 向服务端发起连接请求,这个时候客户端将发送一个SYN分节(假设其值为J),它告诉服务端我发送数据的初始序列号将是J. 2.服务端收到这个请求后,必须确认(ACK) ...

  5. iOS 开发:TCP三次握手连接

    在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接. 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次握 ...

  6. TCP三次握手,数据传输,四次挥手

    TCP包结构 一个TCP包结构如下: 一个TCP包主要由TCP包头和数据部分组成,包头固定部分为20字节,选项和数据部分根据实际情况设置为4N(N可以为0)字节. 1.16bit源端口和目的端口号,它 ...

  7. 用wireshark抓包分析TCP三次握手、四次挥手以及TCP实现可靠传输的机制

    关于TCP三次握手和四次挥手大家都在<计算机网络>课程里学过,还记得当时高超老师耐心地讲解.大学里我遇到的最好的老师大概就是这位了,虽然他只给我讲过<java程序设计>和< ...

  8. 【linux】关于TCP三次握手和四次挥手

    1.TCP是什么 关于OSI的七层模型 TCP在第四层——Transport层,第四层的数据叫Segment->报文 IP在第三层——Network层,在第三层上的数据叫Packet->数 ...

  9. TCP三次握手及四次挥手详细 转

    一.TCP报文格式        TCP/IP协议的详细信息参看<TCP/IP协议详解>三卷本.下面是TCP报文格式图: 图1 TCP报文格式 上图中有几个字段需要重点介绍下:      ...

随机推荐

  1. 存储-raid

  2. 获取磁盘的 总容量,空余容量,已用容量 【windows】

    使用windows api 输入:盘符字符串 输出:磁盘容量 float get_disk_spaces(const char drive_letter, float & total_spac ...

  3. Cannot find or open the PDB file

    打开VS:工具 --> 选项 --> 调试-->符号接下来就是选择Microsoft,然后确认

  4. Linux网络服务第六章PXE高效能批量网络装机

    1.IP地址配置 2.关闭防火墙以及selinux状态如下 systemctl  stop     firewalld Iptables -F Setenforce 0 三.部署FTP服务 1.安装F ...

  5. KMP & AC自动机

    KMP void kmp(char t[],char p[]) { int n=strlen(t),m=strlen(p); int *f=new int[m]; f[0]=f[1]=0; for(i ...

  6. vue2.x学习笔记(二十五)

    接着前面的内容:https://www.cnblogs.com/yanggb/p/12677019.html. 过滤器 vue允许开发者自定义过滤器,可被用于一些常见的文本格式化.过滤器可以用在两个地 ...

  7. Axure遮罩 or 灯箱

    2019独角兽企业重金招聘Python工程师标准>>> 在做原型设计的时候,常常需要设计弹窗(比如confirm.alert或者弹出面板),加一个全屏的遮罩可以突出要展示的内容,效果 ...

  8. USACO Training Section 1.2 [USACO1.2]方块转换 Transformations

    题目描述 一块N x N(1<=N<=10)正方形的黑白瓦片的图案要被转换成新的正方形图案.写一个程序来找出将原始图案按照以下列转换方法转换成新图案的最小方式: 1:转90度:图案按顺时针 ...

  9. 图论--网络流--最小割 HDU 2485 Destroying the bus stations(最短路+限流建图)

    Problem Description Gabiluso is one of the greatest spies in his country. Now he's trying to complet ...

  10. 简单模拟实现Rxjs Observable

    1.先定义类型 export type Observer = { next: (any) => void, complete?: (any) => void, } export inter ...