版权声明:本文为博主原创文章,转载请注明博客地址: https://cloud.tencent.com/developer/article/1433303
TCP报文段结构
TCP和UDP报文一样的是,首部都包含了源端口号和目的端口号以及校验和字段。一般而言TCP的首部是20字节(通常,这个Options是空的)。TCP的首部长度是可变的。
Receive window用于流量控制,它用于指示接收方愿意接受的字节数量。
head len是指示以4字节为单位的TCP的长度。
TCP是在可靠数据传输原理上建立的,它采用的依然是超时重传。超时重传的最大问题是应该把它设置为多少?我们知道它肯定得大于往返时间(RTT)。大多少?RTT是多少?这些都是我们必须知道的。RTT是一个变量,我们一般是根据统计平均来设置RTT。在RFC 6289文档中给出了合理设置超时时间的公式。
EstimatedRTT是取得的一个指数加权平均。
DevRTT是TRR的偏差(相当于方差),用于估计平均RTT偏离EstimatedRTT的程度。
发送方
TCP的发送方从上层接收到数据,生产具有序列号的TCP报文段,启动定时器。如果超出等待时间,那么重传具有最小序号的未确认报文段,并且重启定时器。如果收到ACK。那么当y(ACK携带的期望下一个报文段序号)>sendbase(当前窗口起始位置),那么滑动窗口到sendbase=y处。发送下一个报文段。
一些重传的情形
左边的情形是ACK丢失了,等待超时之后,发送方重传,接收方将重复接受的92序号的报文段丢弃。
右边的情形是ACK在并未丢失,但是超时了。在重传了92后,收到了ACK100和ACK120,那么不会重传100。
还有一种情形是和右边类似的,但是传输的过程中,ACK100丢失了,ACK120没有丢失。如下图所示。
这种情形下,由于接收方收到了ACK120,那么就说明ACK100已经被正确接收了,不必重传。
快速重传
在实际实现TCP协议的时候,TCP每次重传时都会将下一次的超时时间间隔设置为先前的两倍,而不是在使用公式计算出来的时间。例如初始的超时时间间隔是1s,那么当第一次超时之后,下一次的超时时间间隔就设置为2s。这样的实现带来的一个问题是当某种情形下网络拥塞,导致超时间隔变得很大。这样就会使得TCP的延迟变得很高。幸运的是,我们能够通过接收方返回的冗余ACK进行判断报文段是否丢失。因为当一个报文段丢失的时候,接收方会不断返回同一个ACK,要求重传该报文段。但我们收到冗余ACK到达3次时,那么就重传该报文段,而不是等待超时时间间隔。这就是TCP的快速重传。
3次ACK就重传是根据丢包概率以及性能得出的。并不是说3次就一定是丢包了。
接收方
第二种情况是说,上一个报文段没收到,它的下一个报文段收到了,重传以后收到了上一个报文段,那么立即发送的单个ACK是较大的那个ACK。