浅谈通信网络——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层的主要内容,如果未能解决你的问题,请参考以下文章