本文主要介绍TCP字节的可靠传输原理,基本原理和之前介绍的差不多,但是TCP本身字节实现的时候有一定的差异和优化。

序号和确认号

序号

TCP把数据看成一个无结构的数据流,其序号(Sequence number)是建立在传送的字节流的之上,而不是建立在传输的顺序上。一个TCP报文的序号是该报文段的首字节的字节流编号。

例子,假设应用层发送了一个500 000字节的文件到传输层,传输层的MSS(Max segment size)是1000字节,那么TCP将会为该文件构建500个报文段(每个大小为1000字节),如果初始序列号(ISN:initial sequence number)0,那么第一个报文段的序号分配为0,第二个报文段的序号分配为1000,第三个为2000。。。。。。以此类推,如下图所示。

TCP可靠数据传输原理_TCP

确认号

之前讨论的基本原理中,确认号是当前收到的报文段的序号。但是在TCP的实现中确认号是期望收到的下一个字节的序号,加入主机A给主机B发送了编号为0数据长度为1000的一个报文段,主机B成功接收后传给主机A的确认号应该是1000。

TCP可靠数据传输原理_TCP_02

累计确认

对于接收方来说,TCP永远只确认第一个丢失的字节的序号。对于发送方来说,如果收到确认号N,则代表接收方收到了N以前的所有字节。

下图展示了接收方只确认第一个丢失的序号1000。

TCP可靠数据传输原理_TCP_03

 

下图展示了累计确认在发送方的执行情况,由于在seq0超时前收到了ack2000,说明2000之前的数据已经被全部接收,所有不会在重新传递seq为1的数据,减少了一次重传。

TCP可靠数据传输原理_TCP_04

快速重传

基于累积确认的基础,如果接收方连续三次(可以配置)接收到重复的ACK,可以在超时之前直接重传这个分组。

TCP可靠数据传输原理_TCP_05

上面的这个例子另外需要额外主页,当接收方收到发送方的快速传递的seq100后,直接ack了5000,因为5000之前的字节接收方已经收到了。可以看到快速重传提高了效率。

SACK

Sellective Acknowledgement。如果接受的收到多个不连续的数据分组,接收方的接收缓存中会出现很多的空洞,通过sack功能,接收方可以在把这些空洞通知发送方。这样发送方就会有更多的信息来判断那些数据需要重传。