计算机网络微课堂(湖科大教书匠)TCP部分
TCP的流量控制
一般来说,我们希望数据传输得更快一些。但如果发送方把数据发送得过快,接收方就可能来不及接收,这就会造成数据的丢失。
流量控制(flow control)就是让发送方的发送速率不要太快,要让接收方来得及接收,利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制。
如果主机B接收窗口被调整为0,那么主机A就会启动持续计时器,持续计时器超时,就发送零窗口探测报文(携带1字节数据)。然后主机B要对零窗口探测报文进行确认,并告知自己的接受窗口。
主机B即使接收窗口为0,也必须接受零窗口探测报文段、确认报文段、以及携带有紧急数据的报文段。
零窗口探测报文段也有重传计时器,如果零窗口探测报文段丢失,那么等到重传计时器超时后,零窗口探测报文段会被重传。
TCP的拥塞控制
拥塞控制有四种算法:慢开始,拥塞避免,快重传,快恢复。
cwnd:拥塞窗口(动态变化)
cwnd维护原则:没有出现拥塞,cwnd就增大;出现拥塞,cwnd就减少。
拥塞窗口值是几就能发送几个数据报文段。
发送方将cwnd作为发送窗口swnd,cwnd=swnd。
慢开始门限ssthresh:
当 cwnd < ssthreshde 的时候,使用慢开始算法;
当 cwnd > ssthreshde 的时候,使用拥塞控制算法;
当 cwnd = ssthreshde 的时候,可以使用慢开始算法,也可以使用拥塞控制算法;
慢开始和拥塞避免
**慢开始:**每个传输轮次,发送方每收到一个对新报文段的确认时,就把拥塞窗口值+1。
比如最开始cwnd=1;发送一个,收到一个,cwnd+1=2;第二轮发送两个,收到两个,cwnd+2=4;第三轮发送4个,收到4个,cwnd+4=8。
也就是说,慢开始算法中cwnd值以指数规律增大。
当拥塞窗口值增长到慢开始门限时,就开始拥塞避免算法。
拥塞避免:每个传输轮次后,cwnd值只能线性+1.
传输图中丢失数据包,出现重传计时器超时的情况,判断网络很可能出现拥塞控制:
将ssthresh值更新为发生拥堵时cwnd值的一半;
将cwnd值减少为1,并重新开始执行慢开始算法。
比如图中的cwnd=24,ssthresh就设置为12.
全部过程如图所示:
"慢开始"是指一开始向网络注入的报文段少,并不是指拥塞窗口cwnd增长速度慢;
"拥塞避免"并非指完全能够避免拥塞,而是指在拥塞避免阶段将拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞;
快重传
发送M1报文段,接收方立即确认M1,
发送M2报文段,接收方立即确认M2;
发送M3报文段,丢失,接收方无法回复;
发送M4报文段,接收方重复确认M2;
发送M5报文段,接收方重复确认M2;
发送M6报文段,接收方重复确认M2;
发送方立即重传M3报文段,接收方重复确认M2;
快恢复
发送方将慢开始门限ssthresh值和拥塞窗口cwnd值调整为当前窗口的一半;开始执行拥塞避免算法。
TCP超时重传时间的选择
如果将报文段超时重传的时间,设置得比往返时间RTT的值小,就会引起不必要的重传加重网络负荷。
如果将超时重传的值设置的远大于RTT的值,会导致网络的空闲时间增大,降低了传输效率。
超时重传时间RTO应略大于往返时间RTT。
但是由于下面层次的结构也很复杂,例如每个IP数据报的转发路由可能不同,所以每次传输的往返时间不同。
如下图,RTO的时间略大于RTT0,但是下一次传输的往返时间RTT1比RTT0要长很多,此时的RTO就不适用于作为RTT1的超时重传时间,会导致没必要的重传。
所以不能直接使用某次测量得到的RTT样本来计算超时重传时间RTO。
所以我们计算加权平均往返时间RTTs,超时重传时间RTO略大于RTTs。
RTO计算:
往返时间RTT比较难测量,如果出现重传,容易导致测量的时间不准。
利用Karn算法修正版计算RTO的值:
如下图所示,在第五次传输中,由于RTT5>RTO4的值,所以会发生超时重传,于是此时的RTO5直接等于RTO4的两倍。
TCP可靠传输的实现
TCP基于以字节为单位的滑动窗口来实现可靠传输。
下图:报文段首部中的窗口字段rwnd的值为20------接收方表明自己的接收窗口尺寸为20字节;确认号的字段为31------接收方希望收到的下一个数据的序号是31。序号30为止的数据已经全部正确接收了。
发送根据这两个字段的值构建自己的发送窗口=20.
发送方在没有接到确认的情况下可以将发送窗口里面的数据全部发出,凡是没有确认的数据,在确认之前都需要保留,因为可能会超时重传。
发送窗口的前沿和后沿:
如何描述发送窗口的状态:
滑动窗口的滑动过程建议看原视频P63 5.7部分:
发送窗口的数据已经全部发出后,发送方需要等待接受方的确认才能继续发送数据。
如果迟迟没有确认,重传计时器超时,会重传发生窗口内已发送的数据,并重新启动重传计时器。
一些其他的要点:
TCP的连接建立
TCP连接的三个阶段:
三次握手
TCP规定SYN=1的报文段不能携带数据,但要消耗掉一个序号。
TCP连接由客服端主动发起。
客户发送对于TCP连接请求的确认的确认是否多余?
四次挥手
客户发送的TCP报文段中:
序号seq字段的值u为TCP客户进程之前已发送过的、数据的最后一个字节的序号+1;
序号ack字段的值v为TCP客户进程之前已收到的、数据的最后一个字节的序号+1。
服务器发送的:
序号seq字段的值v为TCP服务器进程之前已发送过的、数据的最后一个字节的序号+1(与上面的ack字段值匹配);
序号ack字段的值u+1是对上面客户发送的seq的确认。
FIN=1和ACK=1表示这是一个TCP释放报文段。
是否有必要使得客户进入时间等待状态?
是有必要的。如果没有时间等待状态就关闭,那么如果最后一次确认丢失了,服务器就会进入无限等待客户确认的状态里,无法关闭。
如果客户出现故障,那么服务器怎么关闭连接?
TCP的首部格式
为了实现可靠传输,TCP采取了面向字节流的方式。
一个TCP报文由首部和数据载荷两部分构成。
**源端口号:**标识发送该TCP报文段的应用进程。
**目的端口号:**标识接收该TCP报文段的应用程序。
**序号:**指出本TCP报文段数据载荷的第一个字节的序号。
**确认号:**为n,表明序号到n-1为止的数据都已正确接收,期待接收序号为n的数据。
只有当确认标志位ACK取值为1时,确认号字段才有效。
一个全双工通信举例:
可以看到发送端的序号和接收端的确认号是对应的,发送端的确认号和接收端的序号也是对应的。
**数据偏移:**指出TCP报文段首部的长度。
保留:占6比特,保留为今后使用,目前为0。
校验和:不重要
**同步标志为SYN:**在TCP建立连接时用来同步序号。
SYN置1表示这是TCP连接报文段。
终止标志位FIN:用来释放TCP连接。
FIN置1表示这是TCP释放报文段。
复位标志位RST:用来复位TCP连接。
推送标志位PSH
紧急标志位URG和紧急指针
接收方会从数据载荷部分取出紧急数据,直接上交应用进程,而不必在接收缓存中排队。
扩展首部:
选项:
填充: