转 TCP中的序号和确认号

在网络分析中,读懂TCP序列号和确认号在的变化趋势,可以帮助我们学习TCP协议以及排查通讯故障,如通过查看序列号和确认号可以确定数据传输是否乱 序。但我在查阅了当前很多资料后发现,它们大多只简单介绍了TCP通讯的过程,并没有对序列号和确认号进行详细介绍,结合实例的讲解就更没有了。近段时间 由于工作的原因,需要对TCP的序列号和确认号进行深入学习,下面便是我学习后的一些知识点总结,希望对TCP序列号和确认号感兴趣的朋友有一定帮助。

[b]1.  序列号和确认号的简介及作用[/b]

TCP协议工作在OSI的传输层,是一种可靠的面向连接的数据流协议,TCP之所以可靠,是因为它保证了传送数据包的顺序。顺序是用一个序列号来保证的。
响应包内也包括一个序列号,表示接收方准备好这个序列号的包。在TCP传送一个数据包时,它会把这个数据包放入重发队列中,同时启动计时器,如果收到了关
于这个包的确认信息,便将此数据包从队列中删除,如果在计时器超时的时候仍然没有收到确认信息,则需要重新发送该数据包。另外,TCP通过数据分段中的序
列号来保证所有传输的数据可以按照正常的顺序进行重组,从而保障数据传输的完整。

[b]2.  TCP的通讯过程[/b]

在TCP通讯中主要有连接的建立、数据的传输、连接的关闭三个过程!每个过程完成不同的工作,而且序列号和确认号在每个过程中的变化都是不同的。

[b]2.1 TCP建立连接[/b]

TCP建立连接,也就是我们常说的三次握手,它需要三步完成。在TCP的三次握手中,发送第一个SYN的一端执行的是主动打开。而接收这个SYN并发回下一个SYN的另一端执行的是被动打开。

这里以客户端向服务器发起连接来说明。

[b]1)  第1步[/b]:客户端向服务器发送一个同步数据包请求建立连接,该数据包中,初始序列号(ISN)是客户端随机产生的一个值,确认号是0;

[b]2)  第2步[/b]:服务器收到这个同步请求数据包后,会对客户端进行一个同步确认。这个数据包中,序列号(ISN)是服务器随机产生的一个值,确认号是客户端的初始序列号+1;

[b]3)  第3步[/b]:客户端收到这个同步确认数据包后,再对服务器进行一个确认。该数据包中,序列号是上一个同步请求数据包中的确认号值,确认号是服务器的初始序列号+1。

[b]注意[/b]:因为一个SYN将占用一个序号,所以要加1。

初始序列号(ISN)随时间而变化的,而且不同的操作系统也会有不同的实现方式,所以每个连接的初始序列号是不同的。TCP连接两端会在建立连接时,交互一些信息,如窗口大小、MSS等,以便为接着的数据传输做准备。

RFC793指出ISN可以看作是一个32bit的计数器,每4ms加1,这样选择序号的目的在于防止在网络中被延迟的分组在以后被重复传输,而导致某个连接的一端对它作错误的判断。

[b]2.2 TCP传输数据[/b]

在TCP建立连接后,就可以开始传输数据了。TCP工作在全双工模式,它可以同时进行双向数据传输。这里为了简化,我们只谈服务器向客户端发送数据的情况,而客户端向服务器发送数据的原理和它是类似的,这里便不重复说明。
服务器向客户端发送一个数据包后,客户端收到这个数据包后,会向服务器发送一个确认数据包。

传输数据的简要过程如下:

[b]1)  发送数据[/b]:服务器向客户端发送一个带有数据的数据包,该数据包中的序列号和确认号与建立连接第三步的数据包中的序列号和确认号相同;

[b]2)  确认收到[/b]:客户端收到该数据包,向服务器发送一个确认数据包,该数据包中,序列号是为上一个数据包中的确认号值,而确认号为服务器发送的上一个数据包中的序列号+所该数据包中所带数据的大小。
数据分段中的序列号可以保证所有传输的数据按照正常的次序进行重组,而且通过确认保证数据传输的完整性。

[b]2.3 TCP关闭连接[/b]

前面我们提到,建立一个连接需要3个步骤,但是关闭一个连接需要经过4个步骤。因为TCP连接是全双工的工作模式,所以每个方向上需要单独关闭。在TCP
关闭连接时,首先关闭的一方(即发送第一个终止数据包的)将执行主动关闭,而另一方(收到这个终止数据包的)再执行被动关闭。

关闭连接的4个步骤如下:

[b]1)  第1步[/b]:服务器完成它的数据发送任务后,会主动向客户端发送一个终止数据包,以关闭在这个方向上的TCP连接。该数据包中,序列号为客户端发送的上一个数据包中的确认号值,而确认号为服务器发送的上一个数据包中的序列号+该数据包所带的数据的大小;

[b]2)  第2步[/b]:客户端收到服务器发送的终止数据包后,将对服务器发送确认信息,以关闭该方向上的TCP连接。这时的数据包中,序列号为第1步中的确认号值,而确认号为第1步的数据包中的序列号+1;

[b]3)  第3步[/b]:同理,客户端完成它的数据发送任务后,就也会向服务器发送一个终止数据包,以关闭在这个方向上的TCP连接,该数据包中,
序列号为服务器发送的上一个数据包中的确认号值,而确认号为客户端发送的上一个数据包中的序列号+该数据包所带数据的大小;

[b]4)  第4步[/b]:服务器收到客户端发送的终止数据包后,将对客户端发送确认信息,以关闭该方向上的TCP连接。这时在数据包中,序列号为第3步中的确认号值,而确认号为第3步数据包中的序列号+1;

[b]注意[/b]:因为FIN和SYN一样,也要占一个序号。理论上服务器在TCP连接关闭时发送的终止数据包中,只有终止位是置1,然后客户端进行确
认。但是在实际的TCP实现中,在终止数据包中,确认位和终止位是同时置为1的,确认位置为1表示对最后一次传输的数据进行确认,终止位置为1表示关闭该
方向的TCP连接。

[b]3.  实际数据包分析[/b]

结合上面的理论,下面我们访问网页来捕获数据包,通过实际的数据包来验证序列号和确认号在TCP连接建立、传输数据以及关闭连接时的变化。

打开科来网络分析系统,首先为减少数据干扰,在过滤器中设置只捕获TCP协议的数据,然后开始捕获,同时,访问[url]www.csna.cn[/url],待页面下载完成后,停止捕获。

此次环境中,客户端为192.168.0.92,服务器为:222.77.187.23。

[b]3.1 TCP建立连接[/b]

在捕获的数据包中,首先我们来查看建立连接的三次握手信息,并且观察数据包中序列号和确认号的变化。为了让大家看的更加明白,我在这里使用了“添加数据包注释”的功能。
我们先来查看建立连接的第一步,如图1所示。
[attach]2061[/attach]
(图1  建立连接第一步)

图1中,客户端向服务器发起一个同步请求数据包,请求连接服务器的80端口,客户端随机产生一个初始序列号(ISN)为2712239078,确认号为0。

[b]注意[/b]:在实际情况中,我们访问网站首先进行的是域名解析,这里我们设置了过滤器所以没有捕获到DNS数据包。
接下来我们再看建立连接的第二步。如图2。
[attach]2062[/attach]
(图2  建立连接第二步)

图2中,服务器收到客户的同步请求数据包后,并向客户端发送一个同步确认数据。这个数据包中,服务器随机产生一个初始序列号(1288781508),同
时,将客户端发送的初始序列号(ISN)加1(2712239078+1=2712239079)以作为确认号发回给客户段进行确认。
我们再来查看建立连接的第三步,如下图3。
[attach]2063[/attach]
(图3  建立连接第三步)

图3中,客户端收到这个同步确认数据包后,再次对服务器进行一次确认。在这个数据包中,序列号为上一个数据包的确认号(2712239079),确认号为
服务器的初始序列号(ISN)加1(1288781508+1=1288781509),以对服务器的同步确认数据包进行确认,这样TCP连接就建立了。

[b]3.2 TCP传输数据[/b]

TCP连接建立后,马上就开始传输数据,这里客户端主动向服务器发送一个GET请求,来提交自己的请求信息。
下面我们就来看客户端发送给服务器的GET请求数据包,如图4所示,
[attach]2064[/attach]
(图4  传输数据)

图4中的是客户端向服务器发送的GET请求据数据包,我们注意看序列号和确认号的值!该数据包中,序列号为2712239079,确认号为1288781509,这和三次握手的第三步的数据包中的序列号和确认号相同。
从图4中看出这个数据包的大小为1018字节,其中减去14字节Ethernet报头,20字节的IP报头,20字节的TCP报头和4字节的
FCS(1018-14-20-20-4=960),得到传输的数据大小为1432。我们将该数据包中的序列号加上该数据大小(即
2712239079+960=2712240039),发现与“下一个序列号”的值完全吻合,也就是下一个数据包中服务器发送给客户端的数据包中的确认
号,如图5所示。
[attach]2065[/attach]
(图5 确认收到)

[b]注意[/b]:“下一个序列号”是科来网络分析系统为了方便用户查找下一个连续数据包,而根据数据包序列号和确认号自动计算得出,该字段在实际数据包中是不存在的。

[b]3.3 TCP关闭连接[/b]

在传输数据完成之后,TCP会关闭连接,这里是服务器主动关闭该方向上的TCP连接。我们继续来观察捕获的数据包,先来看关闭连接的第一步,这里是服务器主动发起关闭,如图6。
[attach]2066[/attach]
(图6  关闭连接第一步)

图6中,服务器向客户端主动发起确认位和终止位同时置为1的数据包,确认位置1表示对最后一次传输的数据进行确认,终止位置1表示关闭该方向的TCP连
接,关闭服务器和客户端的TCP连接。在这个数据包中,序列号为客户端发送的上一个数据包中所带的确认号值(1288781777),而确认号为服务器发
送的上一个数据包中的序列号+该数据包所带的数据的大小(2712238597+1432=2712240039);

然后客户端收到该终止数据包,会对服务器发送一个确认数据包,该数据包中,序列号为第1步中的确认号值(2712240039),而确认号为第1步的数据包中的序列号+1(1288781777+1=1288781778);
我们注意观察序列号和确认号的变化情况,如图7所示。
[attach]2067[/attach]
(图7  关闭连接第二步)

随后,就是来自客户端被动发起的关闭,它与服务器主动发起的关闭同理,只不过这次是被动关闭客户端方向上的TCP连接,我们就不重复说明,如图8和图9所示。
[attach]2068[/attach]
(图8  关闭连接第三步)
[attach]2069[/attach]
(图9  关闭连接第四步)

我们根据以上对TCP的建立连接、传输数据和关闭连接三个过程的抓包分析,成功的验证了前面所说的理论。

时间: 2024-10-06 18:12:27

转 TCP中的序号和确认号的相关文章

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

1.TCP的特点: 基于字节流面向连接可靠传输缓冲传输全双工流量控制 2.头部格式和说明 图源百度.如下图示,就是TCP包的头部结构.可以看到这个头部最少有4x5=20个字节. 另外还需要理解TCP协议是承载在IP协议中的.关于IP协议可以参考:http://www.cnblogs.com/xcywt/p/8067521.html 源端口号和目的端口号:再加上Ip首部的源IP地址和目的IP地址可以唯一确定一个TCP连接数据序号:表示在这个报文段中的第一个数据字节序号确认序号:仅当ACK标志为1时

TCP传输中序号与确认序号的交互

本实验通过SSH远程登录服务器,然后使用Wireshark抓包分析.开头的三次握手已经省略.关于序号的交互过程,需要记住一点:TCP首部中的确认序号表示已成功收到字节,但还不包含确认序号所指的字节,希望下一次能收到确认序号所指的字节. 当在远程登录软件上键入命令时,客户端便开始了数据的发送,TCP头如下: 初始化序列号ISN = 1,这个序列号是客户端对发送数据的一个标记,以1作为起始值.根据SSH包长度计算下一次将会发送的起始序号为65.确认序号为1表示我希望下次收到起始序号为1的TCP包.

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

原文见:http://packetlife.net/blog/2010/jun/7/understanding-tcp-sequence-acknowledgment-numbers/ from:https://blog.csdn.net/a19881029/article/details/38091243 如果你正在读这篇文章,很可能你对TCP“非著名”的“三次握手”或者说“SYN,SYN/ACK,ACK”已经很熟悉了.不幸的是,对很多人来说,对TCP的学习就仅限于此了.尽管年代久远,TCP仍

TCP序列号和确认号介绍

TCP是一种可靠的面向连接的数据流协议,TCP之所以可靠,是因为它保证了数据的传输有序,这是通过一个序列号和确认号来保证的. 序列号的作用: TCP将应用层数据和管理数据的每一字节进行顺序编号,序列号用于指出本报文段携带数据的第一个字节的序列号,(SYN,FIN等算作一个字节数据) 确认号的作用: 通信双方采用确认号来对收到的数据进行确认,该确认号之前(不包括该确认号)的所有数据均已正确收到,希望下次接收序列号为该确认号的数据. TCP建立过程: NO Direction Type Sequen

TCP中的URG标志与PSH标志有什么不同?

为了解决这个问题之前,先复习一下TCP的报头. 一.TCP报头分析 第一行:从左到右表示16位源目标端口号与16位目地端口号,通过端口可以标识互联网上唯一的进程. 第二行:32位序号,用来保证数据的按序到达. 第三行:32位确认号,保证数据的完整性,如果没有收到确认,则进行重发. 第四行:4位首部长度,用来将报头与数据分离的.单位是4字节;保留6位;6位TCP标志,分别为: URG:紧急位,其值为1表示紧急指针有效.表示数据需要优先处理,紧急指针指向的是数据的最后一个字节的位置.从数据开始到紧急

【网络协议】TCP中的四大定时器

前言 对于每个TCP连接,TCP一般要管理4个不同的定时器:重传定时器.坚持定时器.保活定时器.2MSL定时器. 重传定时器 非常明显重传定时器是用来计算TCP报文段的超时重传时间的(至于超时重传时间的确定,这里涉及到一大堆的算法,书上有说,我这里不细谈了).每发送一个报文段就会启动重传定时器,假设在定时器时间到后还没收到对该报文段的确认,就重传该报文段,并将重传定时器复位,又一次计算:假设在规定时间内收到了对该报文段的确认,则撤销该报文段的重传定时器. 坚持定时器 上篇文章中已经提到了,主要是

TCP中的计时器

TCP中的计时器? (1)重传计时器 TCP发送完一个报文段,就设置一个专属于此报文段的计时器,规定时间内收到此报文段的确认,撤销计时器,时间走完还没收到确认包,重传此报文段并重置计时器. (2)持续计时器 客户端收到的确认包窗口是0,便停止发送数据了.过了一会,接收端缓过来劲了,继续发送一个更高序号的字节的确认包,它的窗口大于0,客户端如果收到此确认包,检测到窗口大于0,就会重新发送数据.但是如果此"激活"确认包万一丢失,双方都会永久静默下去(TCP不会重传ACK确认包).所以为每个

TCP中在发送的数据的ACK未回来前,能继续发送其他数据包吗?

##基础## - 对应层数据的名称 - Application  <->  Package - Translation  <->  Segment - Networking   <->  Packet - DataLink     <->  Frame - TCP是一种基于字节流的协议,TCP 中的ACK是接收端期待发送端下一个发来的数据包的序列号 - MSS 是在建立连接时通过SYN数据包中的MSS选项里进行协商的(以太网的MTU能到1500,所以MSS可

ASP.NET(C#)--Repeater中生成“序号”列

需求介绍:在Repeater(Table)中加入“序号”列,从1开始自增,步长为1. 思路:因为“序号”跟Repeater的行号有关,所以要在Repeater的ItemDataBound事件中输出“序号”的值.为方便给“序号”赋值,我们使用Label控件. 注意:Repeater的ItemIndex是从0开始的,而“序号”列是从1开始的,所以ItemIndex要加1. 前台代码如下图所示: 前台代码 <asp:Repeater ID="Repeater1" runat="