前言
序号字段和确认号字段是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个字节