浅谈通信网络——TCP层

Posted daiaiai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈通信网络——TCP层相关的知识,希望对你有一定的参考价值。

需求:

通信的本质是进行信息的传递,而我们希望达到的效果总结起来就两点:快而准。

背景:

基于TCP/IP协议,运行在IP层上的流量将变得不可靠,无法仅仅靠IP层技术保障数据包的准确传达。

TCP协议

由此诞生了TCP协议来保证数据流量尽快准确的到达。

我们来看下TCP协议采用了什么策略来保障的:

 

 

首先是引入了确认机制,也就是在发送到对方后,对方得告知我们确实收到了。

采用这种机制有一个前提,如果你发送很长一段数据包,需要拆分为多个数据包进行多次发送,由此你需要对这些数据包进行标序号,由此告知对方哪个数据包在前,哪个数据包在后,再便于TCP/IP协议栈组合之后,再传达给上层应用程序。另外对方也才能告诉你到底是哪块数据包传送成功了。

比如,A发送了SYN(序列号)为1~25的数据包给B,B会返回一个ACK(=最大序列号+1),这里ACK=26。由此B告诉了A自己确实收到了。

疑问:那B如何告知A没有收到该数据包勒?

采用这种机制,A只有在接收到了ACK之后,才会发送下一个数据包。如果等待一段时间后,还未收到,将再次重新发送该数据包。

缺陷:虽然保证了无误的发送,但是明显这种机制无法达到快速的发送。

           1.每次发送一个数据包,如果有丢失,需要等一个周期,才能知晓丢包,耗时太久;

           2.ACK其实是额外的网络开销,反复的发送加剧了网络负担。

发送优化:

a:

选择一次性发送多个数据包。

问题:一次性到底能够发送多少数据包呢?会不会发送太多造成对方无法接收?

最大发送大小(当前窗口大小)取拥塞窗口和通告window窗口的最小值。

b:

由此引入通告window窗口机制,对方反馈自己能够一次性接收多大的数据包大小。(接收端流量控制窗口)

c:

发送方如何告诉对方自己已经将数据包发送完毕了,并清空本地发送缓存,采用将TCP的PUSH字段置一。(涉及伯克利算法)

d:

针对window大小的计算,需要知道发送多少个包,当然发送方得提前知道每个数据包能够发送多大呢?能够发送的最大值是多少?

针对不同的二层网络,会有不同的数据包大小。比如以太网是1500字节,所谓的MTU。由此除去IP和TCP头部,就是1460字节。

所以TCP协议定义了一个标识位叫MSS,以太网就是1460。也就是以太网接口能够发送的最大数据包大小为1460字节。

在TCP建联的时候,不仅仅会协商window的大小,同时也会协商MSS的大小。发送方和接收方分别告知对方自己的MSS大小,最后以最小者为准,来指导发送方发送数据。

缺陷:只是根据双方的MTU来计算的MSS,并无法知晓路径中网络设备的MTU大小,如果中间设备的MTU设备相对小些,将造成丢包。

 

既然我们谈到了中间网路设备,发送的时候,不仅仅需要考虑收方的情况,还要预测两者之间的网络情况。到底带宽是多少,信号是否稳定,我们并无法直接获知,但可以采用一定的算法来优化。

e:

慢启动算法

意思是慢慢提高发送数据包的速度,即发送单位时间内发送数据包的个数逐渐增加,指数级增长。

f:拥塞窗口(发送方流量控制)

一般分组丢失,表示有拥塞。一般有两种方式:1.发送超时;2.收到重复ACK

 拥塞窗口初始值是1个报文段,每收到一个ACK就增加一个报文段大小。因此很容易得到这是一个2的指数级增长。

 由于最大发送速率前期主要受限于拥塞窗口,也应该是指数级增长。

 但这个发送速率的增长,在慢启动算法里面,有一个阈值,叫慢启动门限ssthresh,默认值是65535字节。

 当发送拥塞的时候,ssthresh会取值为最大发送速率的一半(前面已经说了,该值取拥塞窗口和window窗口的最小值)

 当速率超过ssthresh时候,进入拥塞避免阶段,拥塞窗口将从指数级增长,变为RRT时间内递增加1的线性增长。由此速率也会进入线性增长的过程。除非等于了通告窗口。

g:快速恢复算法

当收到重复ACK后,拥塞窗口并不置1,进入慢启动。而是直接进入拥塞避免。这就是快速恢复算法。

 但是如果是超时的拥塞,拥塞窗口将置1,重新进入慢启动。

接收端优化:

a:

ACK附带数据包发送。

接收数据方,也往往需要发送数据包,在发送数据包的时候,将ACK附带一起发送出去。

b.

经受延迟的ACK。

接收方在接收到数据后,并不立即发送ACK给发送方。己方有数据发送除外。一般采用的是等待200ms再发送最后一个ACK。

 好处:

可以减少ACK的数据包量;

但是重复ACK将不会被延迟,而是会立即发送。

c.

 重复ACK(快速重传算法)

当接收方发现在当前收到数据包里序列号前的数据包,并没有收到。则会将上次发送的ACK反馈给对方。由此告知对方两个信息:

1.上次成功收到序列号后的数据我没有正确收到;2.你需要重新给我发送后续的数据包给我(一般就发送该ACK后的一个数据包,也就是丢失的数据包,不重新发送其他后续的数据包)。

     按照伯里克实现,其实发送方在收到三个重复ACK才会重新发送数据。原因是担心只是由于乱序造成的。而不是真实的丢包。

 

其他

 

naglle算法,

一个TCP连接上最多只能有一个未被确认的未完成的小数据包,在该数据包被确认前,不允许再次发送其他小分组。

本算法理论上可以提高互联网效率,但是却减慢了本地的发送速率。特别是在电脑上的人机交互设备上是必须关闭的。

 

疑问:

同一个连接,如果接收方未及时将数据包上传给上层应用程序,比如由于性能瓶颈,上层应用程序还未来得及获取数据包,而发送方又发来了数据。应该如何处理呢? 

解答:

1.接收方正常反馈ACK的时候,带上当前window=最大window-当前已占用缓存大小(一般为0,但也可能出现错误包等,造成的非0情况);

2.发送方收到后,将停止发送数据;

3.直到接收方将发送window更新,发送到发送方,发送方才重新发送数据。

 

三次握手,四次断链(略)

 

 RRT关于时间戳等(略)

 

RST主动快速断链或者拒绝建链

 

URG(略)

 

TCP的四个定时器

重传定时器、坚持定时器、保活定时器、2MSL定时器

 

华为、思科等公司优化算法(再续)

 

以上是关于浅谈通信网络——TCP层的主要内容,如果未能解决你的问题,请参考以下文章

浅谈HTTP协议

浅谈TCP IP协议栈IP协议解析

浅谈TCP/IP协议

浅谈tcp 与udp

浅谈网络编程

浅谈 TCP 协议