如果你正在读这篇文章,很可能你对TCP“非著名”的“三次握手”或者说“SYN,SYN/ACK,ACK”已经很熟悉了。不幸的是,对很多人来说,对TCP的学习就仅限于此了。尽管年代久远,TCP仍是一个相当复杂并且值得研究的协议。这篇文章的目的是让你能够更加熟练的检查Wireshark中的TCP序列号和确认号

在我们开始之前,确保在Wireshark中打开示例(请到作者原文中下载)并亲自实践一下

示例中仅包含一个单独的HTTP请求,请求的流程是:web浏览器向web服务器请求一个单独的图片文件,服务器返回一个成功的响应(HTTP/1.1200 OK),响应中包含请求的文件。右键示例文件中任意一个TCP包并且选择Follow TCP Stream就可在单独的窗口查看原始的TCP流

客户端请求使用红色显示,服务端响应使用蓝色显示

TCP三次握手(参见:https://blog.csdn.net/weixin_42511320/article/details/104787917)

TCP在其协议头中使用大量的标志位或者说1位(bit)布尔域来控制连接状态,我们最感兴趣的3个标志位如下:

SYN - 创建一个连接

FIN -  终结一个连接

ACK - 确认接收到的数据

就像我们看见的那样,一个包中有可以设置多个标志位

选择Wireshark中的“包”1并且展开中间面板的TCP层解析,然后展开TCP头中的标志位域,这里我们可以看见所有解析出来的TCP标志位,需要注意的是,“包1”设置了SYN标志位

使用同样的方式操作“包2”。可以看到"包2"设置了2个标志位:ACK - 用来确认收到客户端的SYN包,SYN - 用来表明服务端也希望建立TCP连接

从客户端发来的“包3”只设置了ACK标志位。这3个包完成了最初的TCP3次握手

序列号和确认号

TCP会话的每一端都包含一个32位(bit)的序列号,该序列号被用来跟踪该端发送的数据量。每一个包中都包含序列号,在接收端则通过确认号用来通知发送端数据成功接收

当某个主机开启一个TCP会话时,他的初始序列号是随机的,可能是0和4,294,967,295之间的任意值,然而,像Wireshark这种工具,通常显示的都是相对序列号/确认号,而不是实际序列号/确认号,相对序列号/确认号是和TCP会话的初始序列号相关联的。这是很方便的,因为比起真实序列号/确认号,跟踪更小的相对序列号/确认号会相对容易一些

原文评论:

序列号应该不是随机的,而是由双方协商的,协商之前最开始的值由TCP运输层生成。 它可能是上一个该端口的序列号+1 , 原因是为了避免上次已断开的连接,还存在网络中延迟到达的TCP报文段的序号与当前连接中等待报文段的序号相同, 以至于认为是这一次连接的包,发生错误。

关与第一点序列号随机问题,我稍有补充。 初始序列号确实是“随机”生成的,一般是基于时间,利用散列函数(这个函数一定时间也会轮换)计算而成的,目的是防止被猜测序列号从而被伪造攻击。同时因为是基于时间的,所以几乎不会与最近断开的或正在等待中的序列号相同,2的32次方中碰巧相同,还是很难的 ̄ω ̄

比如,在“包1”中,最初的相对序列号的值是0,但是最下方面板中的ASCII码显示真实序列号的值是0xf61c6cbe,转化为10进制为4129057982

如果想要关闭相对序列号/确认号,可以选择Wireshark菜单栏中的 Edit -> Preferences ->protocols ->TCP,去掉Relative sequence number后面勾选框中的√即可

需要注意的是,文章接下来的部分依然使用相对序列号/确认号

为了更好的理解在整个TCP会话期间,TCP序列号和确认号是如何工作的,我们可以使用Wireshark内置的绘制流功能,选择菜单栏中的 Statistics ->Flow Graph...->TCP flow ->OK

Wireshark会自动创建一个TCP流的图形摘要

每行代表一个单独的TCP包,左边列显示时间,中间列显示包的方向、TCP端口、段长度和设置的标志位,右边列以10进制的方式显示相关序列号/确认号,在这里选中任意行会高亮主窗口中该行所关联的包

我们可以利用这个流图更好的理解序列号和确认号是如何工作的

包1

TCP会话的每一端的序列号都从0开始,同样的,确认号也从0开始,因为此时通话还未开始,没有通话的另一端需要确认(我使用的Wireshark版本和原作者不同,Wireshark1.10.2中,包1不显示确认号)

包2

服务端响应客户端的请求,响应中附带序列号0(由于这是服务端在该次TCP会话中发送的第一个包,所以序列号为0)和相对确认号1(表明服务端收到了客户端发送的包1中的SYN)

原文评论:

关于ACK+1,在文中“包2”中如下所述:

“需要注意的是,尽管客户端没有发送任何有效数据,确认号还是被加1

这是因为接收的包中包含SYN或FIN标志位 (并不会对有效数据的计数产生影响,因为含有SYN或FIN标志位的包并不携带有效数据)”

这实际上是误解,因此误导了很多人。 在停-等协议中,ACK确认的是当前包的序列号Seq=1 ,接收端会传回 ACK=1 。标识接收到了Seq=1的包,这是我们认为理所当然的。

但是在TCP协议中不是这样, 当发生Seq=1的包,接受端会传回ACK=2, 也就是将接受到的Seq+1 , 代表的是期望接受到的下一个包是 Seq=2的包。 (换句话说,和头部的标志位并没有任何关系)

为什么要这样呢?.. 这么做比较违反我们的直觉。

因为TCP是以流水线发出的,比如发送端顺序的发出 Seq=1、Seq=2、Seq=3

那么如果ACK确认的序号和收到的包的序号一致的话,那么需要发回 ACK=1、ACK=2、ACK=3 共三个包

但是TCP协议对此进行了优化,只需要发送一个ACK包就能代表说自己已经收到了前面三个包, 那就是发送ACK=4 (期望收到Seq为4的包)。这样节省了ACK确认的数量。

另外TCP是的序号是根据数据流编码的, 假设最开始Seq=0 Len=3, 那么 ACK=4的时候:

第一个意思是想表明期待收到下一个Seq为4的包。

第二个意思实际上是说,想收到的包开始的那个比特位于数据流中的第四个比特。(下次从数据流中的第四个Byte开始发送) (实际上上面两个意思是一样的 = = ,同时也再次说明这个ACK+1和头部的标志位无关)

需要注意的是,尽管客户端没有发送任何有效数据,确认号还是被加1,这是因为接收的包中包含SYN或FIN标志位(并不会对有效数据的计数产生影响,因为含有SYN或FIN标志位的包并不携带有效数据)

包3

和包2中一样,客户端使用确认号1响应服务端的序列号0,同时响应中也包含了客户端自己的序列号(由于服务端发送的包中确认收到了客户端发送的SYN,故客户端的序列号由0变为1)

此时,通信的两端的序列号都为1,通信两端的序列号增1发生在所有TCP会话的建立过程中

包4

这是流中第一个携带有效数据的包(确切的说,是客户端发送的HTTP请求),序列号依然为1,因为到上个包为止,还没有发送任何数据,确认号也保持1不变,因为客户端没有从服务端接收到任何数据

需要注意的是,包中有效数据的长度为725字节

包5

当上层处理HTTP请求时,服务端发送该包来确认客户端在包4中发来的数据,需要注意的是,确认号的值增加了725(725是包4中有效数据长度),变为726,简单来说,服务端以此来告知客户端端,目前为止,我总共收到了726字节的数据,服务端的序列号保持为1不变

包6

这个包标志着服务端返回HTTP响应的开始,序列号依然为1,因为服务端在该包之前返回的包中都不带有有效数据,该包带有1448字节的有效数据

包7

由于上个数据包的发送,TCP客户端的序列号增长至726,从服务端接收了1448字节的数据,客户端的确认号由1增长至1449

在抓包文件的主体部分,我们可以看到上述过程的不断的重复,客户端的序列号一直是726,因为客户端除了最初的725字节数据没有再向服务端发送数据,服务端的序列号则与此相反,由于服务端不断的发送HTTP响应,故其序列号一直在增长

序列号为当前端成功发送的数据位数,确认号为当前端成功接收的数据位数,SYN标志位和FIN标志位也要占1位

关闭连接

包38

在确认了服务端发送过来的最后一个数据段之后,客户端将处理整个HTTP响应并决定不需要进一步通信了。此时客户端发送设置了FIN标志位的包38,其确认号和之前的包37一样

包39

服务端通过将确认号加1的方式回应客户端期望关闭连接的请求(这里和包2中确认SYN标志位时所作的操作是一样的),同时设置当前包的FIN标志位

包40

客户端发送最终序列号727,通过将确认号加1的方式确认服务端的FIN包

此时,通信双方都终结了会话并且可以释放用于维持会话所占用的资源

通过wireshark理解TCP序列号和确认号相关推荐

  1. TCP 序列号和确认号是如何变化的?

    大家好,我是小林. 在网站上回答了很多人的问题,我发现很多人对 TCP 序列号和确认号的变化都是懵懵懂懂的,只知道三次握手和四次挥手过程中,ACK 报文中确认号要 +1,然后数据传输中 TCP 序列号 ...

  2. 计算机网络---TCP序列号和确认号

    写在前面: 在网络分析中,读懂TCP序列号和确认号在的变化趋势,可以帮助我们 学习TCP协议以及排查通讯故障,如通过查看序列号和确认号可以确定数据传输是否乱序. 1. 序列号和确认号的简介及作用 TC ...

  3. TCP序列号和确认号

    这里分两种情况来讲: 一.三次握手 第1步:客户端向服务器发送一个同步数据包请求建立连接,该数据包中,初始序列号(ISN)是客户端随机产生的一个值,确认号是0: 第2步:服务器收到这个同步请求数据包后 ...

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

    原文见:http://packetlife.net/blog/2010/jun/7/understanding-tcp-sequence-acknowledgment-numbers/ from:ht ...

  5. 转:理解TCP序列号(Sequence Number)和确认号(Acknowledgment Number)

    http://blog.csdn.net/a19881029/article/details/38091243 原文见:http://packetlife.net/blog/2010/jun/7/un ...

  6. 对tcp三次握手的详解之 理解TCP序列号(Sequence Number)和确认号(Acknowledgment Number)

    重要 !!!!!!!!!       转载自[怀揣梦想,努力前行] 对tcp三次握手的详解之 理解TCP序列号(Sequence Number)和确认号(Acknowledgment Number) ...

  7. TCP三次握手的序列号和确认号

    第一次握手:客户端发送:序列号是随机数x: 第二次握手:服务端回:序列号随机数y,确认号x+1: 第三次握手:客户端回:序列号x+1,确认号y+1

  8. TCP标志位syn,ack,fin以及序列号(seq),响应号(ack)

    一,三次握手 TCP使用三次握手建立一个连接: 第一次握手:客户端发送SYN包至服务器,并进入SYN_SENT状态,等待服务器确认 第二次握手:服务器收到客户端的SYN包,发送一个ACK,同时发送自己 ...

  9. TCP头部分析与确认号的理解

    TCP头部分析与确认号的理解 https://www.cnblogs.com/xcywt/p/8075623.html TCP协议(1)--TCP首部 https://blog.csdn.net/la ...

最新文章

  1. python批量删除文件1001python批量删除文件_Python实现递归遍历文件夹并删除文件...
  2. 习题7 7-7 字符排队
  3. Linux 设备管理和进程管理
  4. 大数据(流量表)任务问题清洗生成新分区表过程
  5. ubuntu 18.04使用sysbench测试MySQL性能
  6. java基础之----java常见异常及代码示例
  7. mysql 5.6 bug_MySQL 5.6的一个bug引发的故障
  8. [Python] 探索性编程与idleX
  9. IDM下载器使用教程
  10. 电气工程计算机网络基础知识大全,2018年注册电气工程师考试(电气与信息技术公共基础)知识点复习:计算机基础[网络体系结构与协议]...
  11. python随机生成电话号码
  12. 计算机无法设置ip地址,如何解决Windows8无法设置静态IP地址的问题
  13. qq空间进入游戏显示服务器拒绝,显示ptlogin2.qq.com,QQ空间打不开的快速解决办法...
  14. DevOps落地实践:BAT系列:敏捷看板:iCafe vs Tapd
  15. Docker——Docker 容器数据卷(Volumes)
  16. HTML5特效(shadow、gradient、transition、transform、filter)
  17. java poi打印excel_POI打印Excel报表
  18. 选择企业最合适的人才 —— 谈谈因人设岗与因事设岗
  19. 软重启、硬重启、重启、重置概念介绍
  20. 小白MAC下安装Caffe 2019最新血泪史

热门文章

  1. 旧手机很卡该如何清理才能变得流畅一些?
  2. 教育部规定计算机是基础学科,同济大学获批4个教育部基础学科拔尖学生培养计划2.0基地...
  3. python 内存泄漏分析工具_记一次调试python内存泄露的问题
  4. OpenCV基础(16)OpenCV直方图均衡化和自适应直方图均衡化(CLAHE)
  5. 最后一次团队作业-总结
  6. 利用baidu的api和python的GUI实现通用文字识别功能
  7. 第2课-OC对象原理上-1
  8. WinPcap网络编程入门——0. 环境配置及系列介绍
  9. iphone12和iphone12pro的区别
  10. laravel - 查询构建器2