TCP扫盲2

对应到网络协议上,就是客户端每发送的一个包,服务器端都应该有个回复,如果服务器端超过一定的 时间没有回复,客户端就会重新发送这个包,直到有回复。

如何实现一个靠谱的协议?

为了保证顺序性,每一个包都有一个 ID。在建立连接的时候,会商定 起始的 ID 是什么,然后按照 ID 一个个发送。为了保证不丢包,对于发送的包都要进行应答,但是这个 应答也不是一个一个来的,而是会应答某个之前的 ID,表示都收到了,这种模式称为累计确认或者累计 应答(cumulative acknowledgment)。

为了记录所有发送的包和接收的包,TCP 也需要发送端和接收端分别都有缓存来保存这些记录。发送端 的缓存里是按照包的 ID 一个个排列,根据处理的情况分成四个部分。

第一部分:发送了并且已经确认的。这部分就是你交代下属的,并且也做完了的,应该划掉的。

第二部分:发送了并且尚未确认的。这部分是你交代下属的,但是还没做完的,需要等待做完的回复之 后,才能划掉。

第三部分:没有发送,但是已经等待发送的。这部分是你还没有交代给下属,但是马上就要交代的。

第四部分:没有发送,并且暂时还不会发送的。这部分是你还没有交代给下属,而且暂时还不会交代给 下属的。

发送端需要保持下面的数据结构。

接收端数据结构。

流量控制问题

我们再来看流量控制机制,在对于包的确认中,同时会携带一个窗口的大小。

我们先假设窗口不变的情况,窗口始终为 9。4 的确认来的时候,会右移一个,这个时候第 13 个包也可 以发送了。

如果发送端传输的过快,但是接收端又处理过慢;或者接收端处理卡住了。这时候我们就需要将发送端的窗口设置为0,停止发送。

如果这样的话,发送方会定时发送窗口探测数据包,看是否有机会调整窗口的大小。当接收方比较慢的 时候,要防止低能窗口综合征,别空出一个字节来就赶快告诉发送方,然后马上又填满了,可以当窗口 太小的时候,不更新窗口,直到达到一定大小,或者缓冲区一半为空,才更新窗口。

拥塞控制问题

拥塞的一种表现形式是丢包,需要超时重传,这个时候,将 sshresh 设为 cwnd/2,将 cwnd 设为 1, 重新开始慢启动。这真是一旦超时重传,马上回到解放前。但是这种方式太激进了,将一个高速的传输 速度一下子停了下来,会造成网络卡顿。

快速重传算法。当接收端发现丢了一个中间包的时候,发送三次前一个包的 ACK,于是发 送端就会快速的重传,不必等待超时再重传。TCP 认为这种情况不严重,因为大部分没丢,只丢了一小 部分,cwnd 减半为 cwnd/2,然后 sshthresh = cwnd,当三个包返回的时候,cwnd = sshthresh + 3,也就是没有一夜回到解放前,而是还在比较高的值,呈线性增长。

小结

顺序问题、丢包问题、流量控制都是通过滑动窗口来解决的,这其实就相当于你领导和你的工作备忘 录,布置过的工作要有编号,干完了有反馈,活不能派太多,也不能太少;

拥塞控制是通过拥塞窗口来解决的,相当于往管道里面倒水,快了容易溢出,慢了浪费带宽,要摸着 石头过河,找到最优值。

参考刘超老师《趣谈网络协议》

猜你喜欢

转载自www.cnblogs.com/CherryTab/p/12213150.html