菜鸟笔记
提升您的技术认知

TCP报文段中的序号和确认号

前言

序号字段和确认号字段是TCP报文段首部中两个最重要的字段,这两个字段是TCP可靠传输服务的关键部分。
TCP把数据看成一个无结构的、有序的字节流。序号是建立在传送的字符流之上的,而不是建立在传送的报文段的序列之上
序号(32bit)

一个报文段的序号是该报文段首字节的字节流编号,举个栗子~

假设主机A的一个进程想通过一条TCP连接向主机B上的一个进程发送一个数据流,主机A中的TCP将隐式地对数据流中的每一个字节编号。假定数据流由一个包含500 000字节的文件组成,其MSS(最大报文段长度)为1000字节,数据流的首字节编号是0,如下图所示:

                  

该TCP将为该数据流构建500个报文段,给第一个报文段分配序号0,第二个报文段分配序号1000,以此类推,每一个序号被填入到相应TCP报文段首部的序号字段中。

确认号(32bit)

TCP是全双工的,即主机A在向主机B发送数据的同时,也许也在接收来自主机B的数据。从主机B到达的每个报文段中都有一个序号用于从B流向A的数据。主机A填充进报文段的确认号是主机A期望从主机B收到的下一字节的序号,举栗子说明:

假设主机A已经收到了来自主机B的编号为0-535的所有字节,同时假设它打算发送一个报文段给主机B,主机A等待主机B的数据流中字节536及其后的所有字节,所以主机A会在它发往主机B的报文段的确认号字段中填上536。

再举一个栗子~

假设主机A已收到主机B的包含字节0-535字节的报文段,以及另一个包含字节900-1000的报文段。由于某种原因,主机A还没有收到字节536-899的报文段。在这个例子里,主机A为了重新构建主机B的数据流,仍在等待字节536(和其后的字节)。因此,A到B的下一个报文段将在确认号字段中包含536。因为TCP只确认该流中到第一个丢失字节为止的字节,所以TCP提供的是累积确认。

主机A虽然收到了字节900-1000的报文段,但是并不会在下一个发往主机B的报文段的确认号字段中填1001,因为535后面的字节还没有得到确认,而收到的900-1000字节的报文段属于失序到达,对于失序到达的报文段的处理方法由TCP编程人员去具体实现,有两个基本选择:一是丢弃失序报文段,二是保留失序字节并等待缺少的字节以填补该间隔(这是实践中采用的方法)

292报文:

seq:19192  len:116

293报文:

ack:19208 = 1912 +116

结论:293号报文的ack表示已经收到292号报文的116个字节