首页 > 代码库 > TCP可靠传输的实现

TCP可靠传输的实现

假设我们讨论A向B发送数据,A端有发送窗口,B端有接受窗口

根据 B 给出的窗口值 A 构造出自己的发送窗口,假如A收到了B的确认报文,此时窗口的值为20,确认序号的值为31,那么接收端会构造出下面的窗口

技术分享

这里面前后沿可以不动和前移,但是前沿可以后移(不建议)

下面我们讨论发送窗口

(1)发送窗口表示,里面的数据在未收到确认数据报之前,都可以连续发送,但是发送了的,必须保留,以便于重传

(2)如果窗口越大,那么可以连续发送的却多,但是前提是接收窗口可以及时接收

(3)发送窗口后沿的部分表示已经确认的,所以不会后移,如果前移(收到确认),不动(未收到确认),前沿可能前移和后移,但是不建议后移,可能收到了确认报文,告诉源主机减小窗口

 

假设发送了11个字节,但是为收到确认

技术分享

 

 

P3 – P1 = A 的发送窗口(又称为通知窗口)

P2 – P1 = 已发送但尚未收到确认的字节数

P3 – P2 = 允许发送但尚未发送的字节数(又称为可用窗口)

从上面可以看到保存一个窗口需要3个指针

 

下面假设收到了31号字节,并把31-33号字节交付给主机,删除,并将窗口向前移动3个序号,同事给A发送信号,此时确认号shi34

 

技术分享

 

A 的发送窗口内的序号都已用完, 但还没有再收到确认,必须停止发送。可能是网络的原因,入过超时,那么需要重传一次

技术分享

前面说过缓存的问题,我们讨论一下缓存和窗口的问题:

(1)缓冲和序号都是有限的,而且是环装的可以重复利用

技术分享

 

 上面是发送缓冲,里面主要有应用程序发给发送方的数据(未发送)还有tcp已经发出,但是未收到确认的数据

 

 技术分享

接收缓存

(1)按照顺序到达,但是没有被应用程序接收的,没有按顺序到达,的

 

 

注意:

(1)虽然发送方的窗口是根据接收方的确认数据确定的,但是双方并不总是一样大,因为网络时间延时的问题

(2)对于不按照顺序到达的,tcp没有强制规定,但是通常保存在窗口中一会

(3)tcp要求接收方必须有累积确认的功能,这样可以减少网络通信,但是推送发送的时间不同太长,否则会发生重传的机制,通常不超过(0.5s)

 

超时重传时间的选择:

 TCP每发送一个报文段,就对这个报文段设置一次计时器。只要计时器设置的重传时间到还没有收到确认,就要重传这个报文段。由于数据链路层和运输层的往返实验概率分布存在很大差异,因此有必要选择合适的超时重传时间。
     报文段的往返时延是指收到确认报文的时间与每一个报文段发出的时间之差。报文段的平均往返时延RTT是由各个报文段的往返时延样本加权平均得出来的。计算公式为:
     平均往返时延RTT=α×(旧的RTT)+(1-α)×(新的往返时延样本),1 ≤ α < 1 典型的值为α为7/8.
 
     即使有一个好的RTT,要选择一个合适的超时重传时间RTO(Restransmission Time out)仍然不是一个容易的事情。, 显然RTO要大于RTT。其计算公式为 RTO = β × RTT, β > 1, 推荐是2

 

选择确认SACK

接收方收到了和前面的字节流不连续的两个字节块。 如果这些字节的序号都在接收窗口之内,那么接收方就先收下这些数据,但要把这些信息准确地告诉发送方,使发送方不要再重复发送这些已收到的数据。

技术分享

和前后字节不连续的每一个字节块都有两个边界: 左边界和右边界。图中用四个指针标记这些边界。 第一个字节块的左边界 L1 = 1501,但右边界 R1 = 3001。 左边界指出字节块的第一个字节的序号,但右边界减 1 才是 字节块中的最后一个序号。 第二个字节块的左边界 L2 = 3501,而右边界 R2 = 4501。

如果要使用SACK那么这些信息需要存在首部可选部分,最多只能使用4个字节快  4*4*2=32  +2(1个字节指明SACK选项,另一个指明这个选项用多少字节)

 

TCP可靠传输的实现