4. 可靠传输
4.1 停止等待协议
(1)无差错情况(如图a):每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组,这叫做“停止等待”。
(2)出现差错或丢失(如图b)
①A发送的M1在传输过程中被路由器丢弃,或B接收M1时检测到了差错就会丢弃M1,然后什么也不错。
②在这两种情况下,B都不会发送任何信息。而当A计时发现计时到期之前M1没有得到确认,会认为刚才发送的M1分组丢失,于是重传前面的M1分组,这也叫超时重传
(3)确认丢失或确认迟到
①图c表示当B发送对M1的确认包丢失,A在设定的超时重传时间内没收到确认,于是重新发送M1分组。但这种情况下,A是无法知道到底是自己发送分组出错或丢失还是B确认包丢失了。可是由于发送了两次的M1分组,此时B应做两个动作:第一是丢弃这个重复的分组M1。第二是向A发送确认,不能认为己经发送确认就不再发送,因为A之所以重传M2就表示A没收到M2的确认。
②图d表示B发送的对分组M1的确认迟到了。A会收到重复的确认,这种情况对确认的处理很简单,就是收下后丢弃。而B仍然会收到重复的M1,并且同样要丢弃重复的M1并向A确认分组M1。
4.2 改进的停止等待协议:连续ARQ协议
(1)自动重传请求(Automatic Repeat request, ARQ):上述可靠传输协议也叫自动重传请求。意思是重传是自动进行的,只要没收到确认,发送方就重传,接收方不需要请求发送重传的某个出错分组。
(2)改进的停止等待协议
①由于使用“停止等待”协议的网络中,主机每发送一个分组就停止发送,等待另一方的确认,使用网络的利用效果很低。
②改进方法:在发送端A设置一个发送窗口(单位是字节)。假设发送窗口是400字节,一个分组有100个字节。这样一个发送窗口中就有M1、M2、M3和M4四个分组,发送端A可以连续发送这四个分组,发送完毕后停止发送,接收方收到这四个连续分组后只需给A发送一个M4的确认。A收到这个确认后,向前滑动窗口继续发送后面的分组。
③对比停止等待协议与连续ARQ和滑动窗口协议,在相同的时间里停止协议只发送4个分组,而后者可以发送8个分组。
4.3 以字节为单位的滑动窗口技术
(1)计算机A和B通信之前先建立TCP连接。并协商参数(如,B告诉A其接收窗口为400字节,A将其发送窗口设置为400字节)
(2)在t1时刻,A发送缓存已放入800字节的数据(假设,一个分组100字节,共8个分组)。由于发送窗口为400字节,首先在窗口内的数据为第1~4个分组,A会按顺序发送给B。(注意在没有收到B的确认,就不能从发送窗口中删除这4个分组,因为丢失或错误时需重传)
(3)在t2时刻,B收到四个分组放入缓存中的接收窗口,按TCP首部的序号排序分组,当窗口中的分组编号连续时,接收窗口向前移动。应用程序按顺序读取接收窗口外连续的分组数据。
(4)B向A发送一个确认(ACK=1,ack=401,大写表示TCP首部ACK标记位,小写表示确认号)
(5)在t3时刻,A收到B的确认,确认号为401,发送窗口向前移动,401后面(第5~8分组)的字节进入发送窗口。A将发送窗口的数据按顺序发出,并将第1~4分组这些己经确认发送成功的分组从缓存中删除。
(6)第5~8四个分组在发送过程中,第7个分组丢失或出错误。
(7)在t4时刻,B收到了5、6、8三个分组。接收窗口只能向前移动200个字节,等待第7个分组,第5、6分组移出接收窗口,应用程序就可以读取这些字节并将其删除。
(8)B向A发送一个确认(ack=601),告诉A己经成功接收到600以前的字节,可以从第601字节开始发送。
(9)A收到确认后,发送窗口向前移动200个字节。这样第9、10个分组进入发送窗口并被发送,第7个分组也会被重传。(注意,如果双方支持选择确认(SACK),那么确认号为601数据包中会包含己经收到的第8个分组的边界,这样发送方就无须再重复发送第8个分组。否则,如果不支持SACK,则第8个分组也会被发送)
(10)B收到第7个分组后,接收窗口的分组序号就能连续,接收窗口向前移动,同时给A发送确认,序号为1001。
(11)A收到确认后,发送窗口前移,按序发送窗口中的分组。以此类推,直至完成数据发送。
4.4 改进的确认:选择确认(SACK)
(1)“确认”存在的问题:如果发送序列中间的某个数据包丢失,TCP会重传最后确认的分组的后续分组,这样原先己经正确传输的分组也可能重复发送,降低了TCP性能。
(2)选择确认(SACK):只重传丢失或出错的分组
①“选择确认”要求接收方告诉发送方哪些数据丢弃(或出错),哪些己经收到。其中的SACK选项(如上图)可以使TCP发送方只发送丢弃的数据而不用发送后续全部数据,提高了数据的传输效率。
②上图发送的3个分组中(假设发送窗口是3个分组大小)的第2分组丢失。接收方发送的确认号为49641,并在SACK中指明了己经收到的第3个分组的边界。这样发送方移动发送窗口后就无需再重传第3个分组。
③注意: TCP首部的“选项”字段最长为40个字节,而指明一个边界需要用掉4个字节,一个分组有两个边界。即要指明一个分组边界需要8个字节。因此,TCP选项中最多只能用来指明(40-2)/8=4个己接收分组。(注意,其中的2表示kind字段和length字段占用的字节数)。
4.5 超时重传的时间调整
(1)TCP Timestamp选项
①发送方在发送报文段时把当前时间放入时间戳(Timestamp)选项字段中
②接收方在确认报文段把上述时间戳字段复制到回送的确认报文中去。
③发送方收到确认报文后,可以通过公式TCP往返传输时间(RTT)=当前时间-数据包中的Timestamp选项中的时间,精确地计算出来并调整超时重传时间。
(2)重传队列中数据包的TCP控制块
①在TCP重传队列中保存着发送而未被确认的数据包,这些数据包中记录了该数据包第一次发送的时间。
②当收到该数据包的确认后,就可以计算出RTT,RTT=当前时间-发送时间。
③实际网络中RTT的计算是相当复杂的。比如,发送一个报文段,到了重传时间过后还没收到确认,就会重传报文,过一段时间后收到了确认的报文段。但很难判定此确认报文是对先发送报文的确认,还是对重传报文的确认。所以这给计算RTT带来很大的麻烦。