TCP的可靠数据传输
1.TCP保证可靠数据传输的方法
TCP主要提供了检验和、序号/确认号、超时重传、最大报文段长度、流量控制等方法实现了可靠数据传输。
检验和
通过检验和的方式,接收端可以检测出来数据是否有差错和异常,假如有差错就会直接丢失该TCP报文段。
序号/确认号
序号:TCP传输时将每个字节的数据都进行了编号,这就是序号,一个报文段的序号字段因此是该报文段首字节的字节流编号。
确认号:主机 A 填充进报文段的确认号是主机 A 期望从主机 B 收到的下一字节的序号。
在上图中,通过序号和确认号,只要发送端有一个报文段传输,接收端没有通过确认号回应(ACK用来保证确认号是有效的),都会重发。或者接收端的响应报文段在网络中丢失了,导致发送端没有收到,也会重发数据。这就可以保证数据的完整性。
超时重传
在进行TCP传输时,TCP每发送一个报文段,都会在一个超时间隔内等待接收方发送回一个ACK确认报文段,如果在这个超时间隔内没有收到ACK确认报文段就会触发超时重传,TCP发送端就会重新发送此报文段。
这个超时间隔是按照3.5.3节的方法动态计算的
最大报文段长度:MSS
在建立TCP的时候,双方约定一个最大报文段长度(MSS)进行发送,重传的时候也是根据这个长度进行重传。
流量控制
一般来说,我们总希望数据传输的更快一些。但如果发送方把数据发得过快,接收方就可能来不及接收,这就会造成数据的丢失。流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。
利用滑动窗口机制可以很方便地在TCP连接上实现发送方流量控制。通过接收方的确认报文中的窗口字段,发送方能够准确地控制发送字节数。
TCP通过让发送方维护一个称为接收窗口的变量来提供流量控制。通俗的说,接收窗口用于给发送方一个指示:该接收方还有多少可用的缓存空间。因为TCP是全双工通信,在连接两端的发送方都各自维护一个接收窗口rwnd,rwnd是动态变化的,下图对变量rwnd进行了图示。
接收窗口rwnd由以下公式得到:
rwnd = RcvBuffer - [LastByteRcvd - LastByteRead]
其中,
LastByteRcvd:接收方上的应用程序从缓存读出的数据流的最后一个字节的编号。
LastByteRead:从网络中到达的并且已放入接收方的接收缓存中的数据流的最后一个字节的编号。
LastByteRcvd - LastByteRead <= RcvBuffer
接收方通过把当前的rwnd值放入它发给发送方的报文段接收窗口字段中,通知发送方它在该连接的缓存中还有多少可用空间。开始时,接收方设定rwnd = RcvBuffer。
发送方轮流跟踪两个变量, LastByteSent和LastByteAcked,这两个变量的意义很明显,注意到这两个变量之间的差 LastByteSent - LastByteAcked,就是发送方发送到连接中但未被确认的数据量, 通过将未确认的数据量控制在值 rwnd 以内,就可以保证发送方不会使接收方的接收缓存溢出。 因此,发送方在该连接的整个生命周期须保证
LastByteSent - LastByteAcked <= rwnd
滑动窗口机制:缓存中会有一个窗口,这个窗口中全部都是发送方已发送但未收到响应ACK的报文段,当窗口中最早的那个已发送但未收到响应收到了响应报文段之后,滑动窗口会右滑。
2.超时间隔加倍
TCP重传具有最小序号的还未被确认的报文段时,如果TCP下次重传的还是此分组,那么会将此分组的超时定时器的时间间隔增加为原先的二倍。
3.快速重传
TCP发送方会在超时事件发生之前通过注意是否有3个冗余的ACK来决定是否重新发送冗余ACK所对应的报文段及之后的报文段。
如果TCP发送方接收到对相同数据的3个冗余ACK,它会把这当做一种暗示,说明跟在这个已被确认过3次的报文段之后的报文段已经丢失,TCP就执行快速重传。
超时间隔加倍和快速重传只是大多数TCP实现中所做的一些修改,并非所有TCP均有此机制