CategoryNetworks

“The Internet and all that it enables is a vast new frontier, full of amazing challenges. There is room for great innovation. Don’t be constrained by today’s technology. Reach out and imagine what could be and then make it happen.” —— Leonard Kleinrock

【转】从TCP到QUIC:从Telnet到HTTP2.0

事情从20世纪70年代开始。

不得不说,人们最初的想法是不要让应用感知网络的存在,分层模型早已有之,网络层协议会处理网络细节。这就使得不管最终谁成了传输协议的标准,都一定要是端到端的。从业务的角度看,人们希望通过网络远程登录一台UNIX主机,这也就使得Telnet成了TCP/IP体系下最为古老的协议之一,一直到今天,我们依然在使用它(虽然现在它已经退化成端口测试工具了)(现在一般用更安全的SSH)。

See also: 【转】End-to-End Principle

我们来看看Telnet这一类程序的特点:

  • 远程输入必须到达主机,一个字节都不能丢;
  • 远程输出必须到达终端显示,一个字节都不能丢;
  • 输入的顺序必须和主机接收的顺序一致,不能乱序;
  • 输出的顺序必须和终端接收的顺序一致,不能乱序。

这写特征可以总结为强时序依赖,你很难跳过一些步骤提前做以后的事情,因为未来的输出依赖于此前的输入。这注定未来承载Telnet的协议需要构建的是一个双向串行流

为了在一个不可靠的网络中构建端到端的可靠的双向串行流,主机需要做什么以及怎么做?

从资源的角度来看,20世纪70年代是一个资源匮乏的年代,无论是带宽还是内存,如果说网络是不可靠的,为了在主机端保证可靠性(*),排队论告诉我们这注定会让主机的内存利用率指数级膨胀,最终系统崩溃。

(*):按照字节顺序排队且不能丢

另一方面,请了解一下停等协议,这应该是最简单的实现上述可靠按序需求的主机端方案(端到端需求)了,嗯,就是它了!

人们很自然地会从停等协议得到扩展,如果能1个字节停等,那就能2个字节停等,那为什么不是n个字节停等?因此,这注定了所谓的TCP协议实现所具有的超级特征,即:

  • n字节停等,n字节积累确认;

【转】ACKnowledgments in TCP

Cumulative ACK

Background: too many ACK segments would waste networking resources which should be used to transfer data from Application Layer.

Cumulative acknowledgment is a process in which the receiver sends a single acknowledgment in response to a finite number …

【转】TCP协议疑难杂症全景解析

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/dog250/article/details/6612496

说明:

1).本文以TCP的发展历程解析容易引起混淆,误会的方方面面
2).本文不会贴大量的源码,大多数是以文字形式描述,我相信文字看起来是要比代码更轻松的
3).针对对象:对TCP已经有了全面了解的人。因为本文不会解析TCP头里面的每一个字段或者3次握手的细节,也不会解释慢启动和快速重传的定义
4).除了《TCP/IP详解》(卷一,卷二)以及《Unix网络编程》以及Linux源代码之外,学习网络更好的资源是RFC

5).本文给出一个提纲,如果想了解细节,请直接查阅RFC

6).翻来覆去,终于找到了这篇备忘,本文基于这篇备忘文档修改。

1.网络协议设计

ISO提出了OSI分层网络模型,这种分层模型是理论上的,TCP/IP最终实现了一个分层的协议模型,每一个层次对应一组网络协议完成一组特定的功能,该组网络协议被其下的层次复用和解复用。这就是分层模型的本质,最终所有的逻辑被编码到线缆或者电磁波。
分层模型是很好理解的,然而对于每一层的协议设计却不是那么容易。TCP/IP的漂亮之处在于:协议越往上层越复杂。我们把网络定义为互相连接在一起的设备,网络的本质作用还是“端到端”的通信,然而希望互相通信的设备并不一定要“直接”连接在一起,因此必然需要一些中间的设备负责转发数据,因此就把连接这些中间设备的线缆上跑的协议定义为链路层协议,实际上所谓链路其实就是始发与一个设备,通过一根线,终止于另一个设备。我们把一条链路称为“一跳”。因此一个端到端的网络包含了“很多跳”。

2.TCP和IP协议

终止于IP协议,我们已经可以完成一个端到端的通信,为何还需要TCP协议?这是一个问题,理解了这个问题,我们就能理解TCP协议为何成了现在这个样子,为何如此“复杂”,为何又如此简单。
正如其名字所展示的那样,TCP的作用是传输控制,也就是控制端到端的传输,那为何这种控制不在IP协议中实现的。答案很简单,那就是这会增加IP协议的复杂性,而IP协议需要的就是简单。这是什么原因造成的呢?
首先我们认识一下为何IP协议是沙漏的细腰部分。它的下层是繁多的链路层协议,这些链路提供了相互截然不同且相差很远的语义,为了互联这些异构的网络,我们需要一个网络层协议起码要提供一些适配的功能,另外它必然不能提供太多的“保证性服务”,因为上层的保证性依赖下层的约束性更强的保证性,你永远无法在一个100M吞吐量的链路之上实现的IP协议保证1000M的吞吐量…
IP协议设计为分组转发协议,每一跳都要经过一个中间节点,路由的设计是TCP/IP网络的另一大创举,这样,IP协议就无需方向性,路由信息和协议本身不再强关联,它们仅仅通过IP地址来关联,因此,IP协议更加简单。路由器作为中间节点也不能太复杂,这涉及到成本问题,因此路由器只负责选路以及转发数据包。
因此传输控制协议必然需要在端点实现。在我们详谈TCP协议之前,首先要看一下它不能做什么,由于IP协议不提供保证,TCP也不能提供依赖于IP下层链路的这种保证,比如带宽,比如时延,这些都是链路层决定的,既然IP协议无法修补,TCP也不能,然而它却能修正始于IP层的一些“不可保证性质”,这些性质包括IP层的不可靠,IP层的不按顺序,IP层的无方向/无连接。
将该小节总结一下,TCP/IP模型从下往上,功能增加,需要实现的设备减少,然而设备的复杂性却在增加,这样保证了成本的最小化,至于性能或者因素,靠软件来调节吧,TCP协议就是这样的软件,实际上最开始的时候,TCP并不考虑性能,效率,公平性,正是考虑了这些,TCP协议才复杂了起来。

3.TCP协议

这是一个纯软件协议,为何将其设计上两个端点,参见上一小节,本节详述TCP协议,中间也穿插一些简短的论述。

3.1.TCP协议

确切的说,TCP协议有两重身份,作为网络协议,它弥补了IP协议尽力而为服务的不足,实现了有连接,可靠传输,报文按序到达。作为一个主机软件,它和UDP以及左右的传输层协议隔离了主机服务和网络,它们可以被看做是一个多路复用/解复用器,将诸多的主机进程数据复用/解复用到IP层。可以看出,不管从哪个角度,TCP都作为一个接口存在,作为网络协议,它和对端的TCP接口,实现TCP的控制逻辑,作为多路复用/解复用器,它和下层IP协议接口,实现协议栈的功能,而这正是分层网络协议模型的基本定义(两类接口,一类和下层接口,另一类和对等层接口)。
我们习惯于将TCP作为协议栈的最顶端,而不把应用层协议当成协议栈的一部分,这部分是因为应用层被TCP/UDP解复用了之后,呈现出了一种太复杂的局面,应用层协议用一种不同截然不同的方式被解释,应用层协议习惯于用类似ASN.1标准来封装,这正体现了TCP协议作为多路复用/解复用器的重要性,由于直接和应用接口,它可以很容易直接被应用控制,实现不同的传输控制策略,这也是TCP被设计到离应用不太远的地方的原因之一。
总之,TCP要点有四,一曰有连接,二曰可靠传输,三曰数据按照到达,四曰端到端流量控制。注意,TCP被设计时只保证这四点,此时它虽然也有些问题,然而很简单,然而更大的问题很快呈现出来,使之不得不考虑和IP网络相关的东西,比如公平性,效率,因此增加了拥塞控制,这样TCP就成了现在这个样子。

3.2.有连接,可靠传输,数据按序到达的TCP

IP协议是没有方向的,数据报传输能到达对端全靠路由,因此它是一跳一跳地到达对端的,只要有一跳没有到达对端的路由,那么数据传输将失败,其实路由也是互联网的核心之一,实际上IP层提供的核心基本功能有两点,第一点是地址管理,第二点就是路由选路。