tcp是一个可靠连接的协议,但不要指望它是什么理论的实现,它是实践的东西,任何实践的东西背后都不是一个理论,而是一大堆理论,tcp正是单一停等,GBN(回退N)以及SR(选择重传)的结合体,单一停等是最原始的理论,但是带宽利用率太低了,后面的GBN实现了流水线式的数据发送和确认,可靠连接的根本就在于确认-ack,而GBN的ack完全是基于接收方的,接收方很简单的只发送最后一个按序到达的报文的序列号最为确认号,而发送端收到以后将重传该确认号之后的所有报文,这样实现很简单,要考虑的事情也不多,但是可能会导致大量不必要的重传动作,因此SR就报上了名来,只要接收端收到一个报文就给予确认,发送方将已经被确认的分组从重传链表删除,然后如果被确认的分组在窗口的最左边,那么向前移动发送窗口,这就解决了GBN中的一系列问题,可是新的问题就是实现起来可能更复杂了,收发双方对于ack的处理都很复杂。
linux的tcp实现实质上是以GBN为根本,但是内置了SR算法的支持,正和RFC的建议一致,SR在RFC2018中被描述,而它是作为一个tcp选项被加入协议的,也就是说tcp的实现的骨架还是gbn,但是如果你想使用sr的特性,那么需要通过tcp头的选项来支持,linux实现了这一点,并且将发送ack,接收ack,处理sr,以及重传等动作完全分离,发送ack完全按照gbn的方式,如果需要sack的话,那么另外填写选项,对于接收ack并处理,也是按照GBN的方式,但是其间需要检查是否冗余ack积累到了一定量,接收ack是tcp_ack处理的,虽然它基于,但它丝毫不必担心gbn的大量重传问题,因为重传动作完全是tcp_ack以外的,它将根据sack相关的信息处理重传,而不是根据gbn的原则重传分组。
正是ack保证了连接的可靠性,同时ack也左右了tcp的拥塞控制以及流量控制动作,进而使得tcp实现带宽的公平性(加增乘减),但是公平性只是针对tcp内部而言的,如果大量疯狂的udp视频传输于骨干网,由于udp没有拥塞控制,它会占去大量资源而不后退,而tcp由于丢包或者延迟已经感觉到了拥塞,于是tcp们纷纷减缓发送,于是就让给udp更大的带宽,虽然这种绥靖不是有意的,但是这个问题却是亟待解决的,目前无法在协议本身找到完美的解决方案,而只能通过诸如路由器的流控或者在linux上使用iptables配置相关策略来实现。
因此tcp是一个诸多理论的混合体,而linux实现的tcp又是诸多实现建议的混合体。
linux关于tcp协议ack的实现--总结和公平性问题
最新推荐文章于 2020-12-29 07:39:04 发布