计算机网络:Internet基本原理(下) 协议层次

847 阅读26分钟

缘起

有很多像我一样毕业后转行的程序员,在大学里可能没有系统地学习过计算机的专业课程。

短时间内看,这些东西在工作中也不会接触到。但是作为一个程序员,计算机网络是必备的知识,在排查复杂问题的时候也会用到。

借用耗子叔的话来说:

打个比方,就像《笑傲江湖》里提到的「气宗和剑宗」。

  • 剑宗功夫易于速成,见效极快。大家都练十年,定是剑宗占上风;各练二十年,那是各擅胜场,难分上下;要到二十年之后,练气宗功夫的才渐渐的越来越强;到得三十年时,练剑宗功夫的便再也不能望气宗之项背了。

剑宗功夫可以速成,但是后劲不足。如果从长远看,还是气宗更为厉害。

而在编程领域,平常学习的框架就是剑宗,见效很快,马上可以上手工作。而基础知识就是气宗,从长远来看很重要。

所以,现在我决定系统地学习计算机基础知识,用博客记录下来。

首先来看计算机网络,我们的教材是 《计算机网络-自顶向下方法(第7版)》,视频是 中科大郑烇、杨坚全套《计算机网络》 https://www.bilibili.com/video/BV1JV411t7ow?p=1

下面我将带你从0到1,快速过一遍计算机网络的基础知识。现在我们来到第一章 Internet,let‘s go!

Internet 结构和 ISP

之前我们按照节点和链路类型划分互联网:网络边缘、网络核心、接入网。

现在按照接触密集程度来划分,在一个网络的设备成为一个 ISP 网络。

给定数百万接入 ISPs,如何将它们互联到一起?

肯定不能直接全部连接在一起,如果将每两个 ISPs 直接相连,不可扩展,而且需要O(N^2) 连接。

  • 端系统通过接入 ISPs (Internet Service Providers)连接到互联网

    • 住宅,公司和大学的ISPs 接入ISPs
  • 接入 ISPs 相应的端系统必须是互联的,因此任何2个端系统可相互发送分组到对方

  • 最终,导致"网络的网络——互联网"非常复杂,他的发展和演化是通过经济和国家的政策来驱动的

分组延时、丢失和吞吐量

分组交换方式,它的共享性比较好,比较适合与计算机之间的通信。

但是分组交换它的好处也不是平白无故获得,它需要耗费很多的代价,另外一方面,它有很多的问题。

一个是会有比他线路交换更多的延迟;另一个是在传输的数据过程当中,分组可能会被丢弃掉。

分组丢失和延时是怎样发生的?

来了一个分组,通过查路由表决定走哪条链路。

  • 如果当前链路上当前没有分组在传输,直接可以传
  • 如果这条链路上有其他的分组正在传输,那么当前分组必须要排在队列当中。

    • 最后排到队头,才能把它放走。这就是分组延时的原因。
  • 当然队列也是有限的,如果当前队列已经溢出了。那么,分组将会被丢弃掉。这就是分组丢失的这样的一个原因。

四种分组延时

那么除了排队延迟之外,还有其他的什么延迟?

  1. 节点处理延时

每来一个分组,节点首先要检查这个分组有没有出错,然后要把它的目标 IP 地址字段提取出来查路由表。

这要做一系列的处理都需要时间,我们把它称之为处理延迟。

  1. 排队延时

查完路由表,我决定通过这条链路把它放出去,但是这条链路上的队列还有其他的分组,这时候就会经历排队延迟

排队延迟的时间是不确定的,依赖于路由器的拥塞程度。

  1. 传输延时 transmission

假定分组以先到先服务的方式传输——这在分组交换网络中是常见的方式,仅当所有已经到达的分组被传输后,才能传输我们的分组。用 L 比特表示分组的长度,用R bps 表示从路由器 A 到路由器 B 的链路传输速率。

传输时延是 L/R。这是将所有分组比特推向链路所需要的时间。

  1. 传播延时 propagation

一旦一个比特被推向链路,该比特需要向路由器B传播,从该链路的起点到路由器B的传播所需要的时间是传播时延。

该比特以该链路的传播速率传播,该传播速率取决于该链路的物理媒介,其速率范围是 m/s,这等于或略小于光速。传播时延等于两台路由器之间的距离除以传播速率,即传播时延是d/s,d 是两台路由器之间的距离,s 是该链路的传播速率。传播时延在毫秒级。

传输时延是路由器将分组推出所需要的时间,它是分组长度和链路传输速率的函数,而与两台路由器之间的距离无关。

传播时延是一个比特从一台路由器向另一台路由器传播所需要的时间,它与两台路由器之间距离的有关。

车队类比

传输 vs 传播

  • 10 个车构成了一个车队,然后车通过第一个收费站,越过高速公路,到达第二个收费站,它的时速是 100 公里/每小时。每个车通过服务站的时候,它要有一些时间,收费员给你发个卡之类的,耗费 12 s,十个车 12 秒一共是 120 秒。

    • 把一个车队的每一个车每个比它打出去的一个时间之和,相当于传输延迟
  • 汽车时速 100 公里,行驶越过 100 公里,需要 60 分钟,这是一个传播延迟

信道的容量

如果汽车以1000km/hr的速度传播汽车,收费站服务每辆车需 1 分钟。

那么在所有的汽车都到达第一个收费站服务之前,汽车会到达第二个收费站吗?

yes! 7分钟后,第一辆汽车到达了第二个收费站,而第一个收费站仍有3辆汽车。

在整个分组被第一个路由器传输完成之前,第一个比特已经到达了第二个路由器!

那这里我们顺便介绍一下一个概念,叫信道的容量。第一个收费站,相当于计算机的局域网 LAN,容量几乎没有。分组还没打完呢,对方都已经收到了。第二个相当于 WAN 广域网,所以说两种的这个情况是完全不一样。

节点延时

所以说在每个节点当中所耽误的时间,处理延迟,排队延迟,传输,传播延迟。

  • 一般来说,处理延迟通常是微秒或者更少。
  • 排队延迟是随机的,取决于当时的拥塞的程度。
  • 传输延迟取决于 L 分组的长度, R 表示从路由器 A 到路由器 B 的链路传输速率。
  • 传播延迟取决于 d 两台路由器之间的距离, s 是该链路的传播速率。

排队延时:流量强度不能大于 1

流量强度,是 (R 链路带宽 x a 分组到达队列的平均速率)/ L 分组长度。

  • 必须在0 -1 之间,零是比较轻载的时候,1 是比较重载的时候。
  • 流量强度等于 0,排队延迟非常少,但是流量强度越接近于 1 ,排队延迟就会趋向于无限大,无限大。

吞吐量

吞吐量指的是什么呢?单位时间,从源主机向目标主机发出去的有效的比特的数量。

🌰 在这个场景当中,有两条链路,从源主机向另外一个主机传,相当于经过两个管道,第一个管道细一点,第二个粗一点。在传输过程中,它的这个有效吞吐量取决于哪个?细的管道,称为瓶颈链路

互联网场景

现在来看一个真实的场景,10 个 主机通过一条链路 R 通信,那么每个主机仅仅能够获得它 1/ 10 的带宽, N 分之一的带宽。

  • 那你说为什么平均呢?我们在讲到这个传输层 TCP 协议的时候,会讲到 TCP 的公平性。
  • 吞吐量由瓶颈链路决定

协议层次和服务模型

怎么实现复杂的系统网络?

网络是一个非常复杂的一个系统。

  • 网络的功能纷繁复杂,要实现数字信号的物理信号承载,点到点的局部传输,端到端的之间的路由传输,要有保证可靠数据的传输,进行进程区分、实现各种各样非常复杂的网络应用
  • 而从互联网的角度来看,它有数百亿个设备,几十亿个用户。互联网上面的流行的应用也达到数千种,可以说是人类规模最大的一个人工系统,也可以说是最复杂的系统之一。

那么你作为一个工程师,你怎么样来设计实现复杂的计算机网络呢?有哪些思路呢?

  • 你可能会想到模块化。把一个比较复杂的功能,分解为一个个的模块,模块之间相互的调用。这种方式是平面性的,任何一个模块,都可以调用其他任何一个模块所提供的功能和服务。这样,就可以把比较复杂的功能通过模块化的方式分解为一个个简单的问题。
  • 另外一个一种解决的思路,是分层的方法。这种方法也是把比较复杂的功能分为一个个的模块,但是只有紧相邻的模块和模块之间,也就是相邻的层级之间,才可以调用和被调用。它不允许或者是不推荐这种跨层的调用。

计算机网络就是采用分层的方式来设计和实现的。科学家把计算机网络分解为一个个功能明确的层次,每一层,通过层间的接口向上层提供服务,一层落一层,最后实现了的复杂的功能。

我们来看看现实生活当中的一个例子,方便大家的理解。

🌰:两位异地哲学家的交流

两位异地的哲学家想做思想交流,一位在美国,一位在法国。

我们可以设置三个层次。

  • 第一层:秘书,解决异地通讯的问题。
  • 第二层:翻译,把哲学家原来用的法语、英语转化为公共语言。
  • 第三层:哲学家,输出哲学思想。

那么分层解决问题的这种方式,有什么好处呢?

  • 第一,把大的问题分解成若干个小问题。比如我们的例子里,把一个复杂问题转换成三个子问题,每个问题的解决相对比较独立,而且比较单一。
  • 第二,便于采用一些新技术。比如在秘书层,原来是靠马车传输信息,后来可以靠电报、电话,提高两个哲学家之间交流的效率。

功能层次

层次化方式实现复杂网络功能

层次

  • 将网络复杂的功能分成功能明确的层次,每一层实现了其中一个或一组功能。
  • 每一层实现的部分功能可以被上层调用,这些功能,我们把它叫做服务。换句话说,每一层通过层间的接口,向上层提供服务。

    • 🌰 怎么向另一个实体发送报文?
  • 借助下层提供的服务来跟对方交换 PDU (协议数据单元),包括本身的处理,包括一些资源的安排。然后最终通过层间的接口,向上层提供更好的服务,一层摞一层,最后实现出计算机网络非常复杂的一个功能。

协议

本身实体交互的过程当中,应该遵守的动作集合规则的集合,我们把它称之为协议

协议是怎么实现的?借助于下层提供的服务。

实现协议的目的是什么呢?是为了向上层提供更好的服务。

本层的服务

借助下层服务实现的本层协议实体之间交互带来的新功能(上层可以利用的) + 更下层所提供的服务

因为这部分内容是整个互联网最核心的内容,所以我们再回顾一遍,怎么样设计实现组织比较复杂的计算机网络。

  • 把计算机网络分成一个个功能,明确的层次,每一层实现一个或一组功能。
  • 采用协议实体的相互动作来具体实现的。

    • 怎么实现交互的动作呢?借助于层间的接口,借助于下层所提供的服务来交换相应的 PDU,从而实现 pdu 的协议动作。这样,可以向上层提供更好的服务。
  • 每一层向上层提供的服务,包括了所有下层向上提供服务的总和。还包括了本层跟对等层的实体交互的过程当中,形成的新的服务特性。否则的话,我要你这一层何用。?你仅仅是底层所提供的服务的一些总和,那是没有用的,你还要形成一些新的功能、新的服务。

服务和服务访问点

然后我们介绍一下术语。

服务

服务是什么呢?底层实体向上层实体提供它们之间的通信的能力。服务是垂直的关系,上层实体通过层间的接口访问下层所提供的服务。

这里有两个概念,服务用户和服务提供者。

服务用户 & 服务提供者

什么叫服务用户?

例如 TCP 的实体上有很多的应用,一个 .net 应用,一个 FTP,一个 web 应用。

对于这个 TCP 的实体来说,是不是有三个同时存在的用户? 我们把他们叫做服务用户。

而向他们提供服务的,叫做服务提供者。

原语 primitive

上层使用下层服务的形式,高层使用低层提供的服务,以及低层向高层提供服务都是通过服务访问原语来进行交互的 —— 形式。

换句话说,用户到底采用什么形式来使用服务提供者提供的服务,服务提供者采用什么形式向用户提供服务,我们把它叫原语 primitive。

🌰 那我们再举打个比方,比如顺丰快递可以提供很多的业务,寄文件、寄电子产品、寄大件物品、收文件等等。你要使用它提供的具体服务,称为原语

🌰 应用进程使用传输层所提供的服务,要借助于一系列 socket 的 api 当中的一些函数,这些函数被叫做原语。

服务访问点 SAP Services Access Point

服务访问点

如果我是一个服务提供者,我同时向三个应用实体提供服务。这个时候来了一条数据,这条数据给哪个应用呢?

所以,我是不是要想办法区别这个数据是给谁的?

因此,就出现了服务访问点,通过在层间的接口上加上一系列的点,用他们来区分不同的上层用户。让下层的服务提供者,来区分不同上层用户的信息。

🌰 例如寄快递,一个快递公司,不可能为只为一个人服务。所以,我们寄快递的时候要填写快递单,记录下你是谁、你从哪里寄出,收件方是谁、他的详细地址。到了对方的快递服务点,他才能区分出这个快递是寄给谁的。

怎么样区分不同的发送方和接收方,这就是服务访问点做的事情。

服务的类型

面向连接的服务

如果两个应用之间建立起一个连接,要先打个招呼,互相说你好。这种服务的这种形式,叫做面向连接的服务。

两个应用进程采用 TCP 所提供的服务。就是一种典型的面向连接的服务。

客户端进程要向服务器端的进程要建立起连接,要主动向对方发起一个连接,对方收到连接请求之后,要给出一个连接确认的回应。换句话说,也就是两个应用进程在通讯之前要先握手

无连接的服务

反正,叫做无连接的服务,比如 UDP 。两个应用进程在通讯之前,不需要握手 🤝,不需要建立连接的。

服务和协议

区别

协议是水平的关系,是对等层实体在通信的过程当中应该遵守的规则的集合。

而服务是垂直的关系。在系统的内部,通过层间的接口在 SAP 上用原语的形式向上层提供服务。

  • 还记得在上面讲的名词吗,我们把他们串起来解释服务是什么。

    • 在一个系统的内部层,相邻两层之间,它的接口上,服务的用户在 SAP 上通过原语,上层使用下层的服务,下层向上层提供服务。
  • 还记得 SAP 和原语吗?

    • 因为很多用户都可以使用下层的服务,下层的一个协议实体可以同时为多个用户提供服务,所以必须要用 SAP 来区分。
  • 因为下层向上层提供的服务有各种各样的类型,而且这些类型在使用的过程当中,有一系列的操作的规范。因此,必须要以原语的形式加以规范和区分。

这张图,勾画了协议和服务的关系。五层借助于层间的接口访问四层提供的服务,依次类推,一直到了第一层。但是物理层直接使用物理媒体来传输物理信号,把数字信号转成物理信号来传播。这是服务和被服务的垂直关系。

而每层实体,在通讯过程当中应该遵守的一些规则,叫协议。

联系

  • 本层协议实现的时候,要借助下层所提供的服务才能实现
  • 实现本次协议的目的是什么?为了向上层提供更好的服务

数据单元(DU)

什么叫数据单元?

对于当前层次 N 来说,它通过层间接口的 SAP 向上 N+1 层提供服务。

  • 那么他要向 N+1 传输数据,我们把这个叫做服务数据单元 SDU。
  • SDU 通过层间接口,它要加上一些接口控制信息(ICI),以便于更加顺利地穿过层间接口,那是他的事,我可以不管。

  • 然后 SDU 拿到之后,在把 SDU 前面再加上本层的控制信息,形成了本层的协议数据单元词 PDU。 也就是说,对层协议实体交换信息,是由第 N 层的 pdu 来实现的。

最核心的内容是什么呢?

  • 每一层的 pdu 都有它的头部和 body。

    • body 来源于上层的交下来的 SDU 数据,上层让本层装载的数据。
  • 头部信息有一部分是 ICI 转过来的,有一部分是本层附加上去的。
  • 🌰 相当于把上层的货物 SDU,装进本层的卡车。卡车分为卡车头、卡车的身体。卡车头装入了头部信息 head, 卡车的身体 body 装了货物 SDU。

后面我们分别每一层的协议数据单元,他们都特殊的称呼。

  • 应用层的数据单元,叫应用报文 message;
  • 传输层叫报文段,或者简称为段 segment;
  • 到了网络层,通常把它叫分组,但如果网络是无连接方式来工作的话,我们又把它数据报,数据报就是一种网络层的分组;
  • 到了链路层,通常把它叫帧;
  • 最后物理层它的协议数据单元,就比较含糊了,叫什么都可以。

就每一层交换的数据单元,它的称呼都是不一样。

分层处理实现复杂系统的好处

分层实现,对于实现复杂的计算机网络系统到底有什么好处呢,我们可以简单来剖析一下。

概念化:结构清晰,便于标示网络组件,以及描述其相互关系

最大的一个好处是什么呢?

可以把一个大的复杂的系统,分解为一个个小的功能,每个功能独立去实现。分而治之,每个功能更好好设计实现了。

结构化:模块化更易于维护和系统升级

第二个好处是什么呢,改变某一层服务的实现不影响系统中的其他层次,可以平滑的升级。

  • 🌰 还是两个哲学家交换哲学问题。

    • 两个秘书原来是采用走的方式来交换信息的,时代进步了,换成电报、电话来交换信息。
  • 而且秘书和翻译的对接的接口是不变得,也就是说底层采用新的技术,对上层来说是无感知的。这样便于整个系统平滑的升级。

问题?

效率比较低,而且层间信息交换比较麻烦。

但总的来说,分层解决网络问题带来的好处要比坏处要多得多,所以计算机网络基本上是采用分层来设计的。

Internet协议栈

那么计算机网络究竟是分为哪几个层次呢?每一个层次的主要功能是什么呢?下面我们来一一揭秘。

  • 计算机网络的功能被分成了五个层次,每一层分别提供相应的功能。物理层、链路层、网络层、传输层和应用层。

物理层

在线路上传送 bit

  • 发送端把上层交下来的帧当中的一个或一组比特变成物理信号,并在介质当中传送给对方。接收方把物理媒体上存在的物理信号,比如电磁波、光信号,还原回原来的数字信号 0101。
  • 🌰 也就是把数字数据转换成物理信号,然后承载在媒体之上,从一点传到相邻的另外一点,例如从计算机传到另外一个交换机的网口上,然后对方的网卡的物理层再把承载在媒体之上的物理信号反转回来,形成原来的数字数据。

链路层

相邻网络节点间的数据传输,通过一段链路把网卡连起来。

  • 在物理层所提供的服务的基础之上,传输以为单位的数据。而且是在相邻两点之间传输以帧为单位的数据。
  • 什么叫相邻两点?两个网口上相连接的,🌰 比如我的计算机连到整个楼层的交换机,他们的网口是相连的,他们就是相邻两点。
  • 当然,有的链路层提供的是可靠服务,有些链路层提供的是不可靠服务。

仅仅有相对来点之间的传输,能够完成源主机到目标主机的数据传递吗?不行,怎么办呢?

网络层

  • 把相邻两点扩展为源节点到目标节点之间、端到端的关系,就是网络层干的事情。也就是在链路层所提供的相邻两点之间的数据传输的基础上,传输以分组为单位的端到端的数据传输。
  • 链路层提供 P2P 的关系,网络层是端到端的关系。在链路层点到点的数据传输的基础上,提供了端到端的数据传输。

仅仅有端到端,网络层提供的服务够不够,对于应用进程直接可以跑起来吗?不能。

传输层

传输层是在网络层之上,借助于网络层主机到主机的传输的服务,细分为到进程的服务。并且将不可靠的通信变成可靠的通信。

  • 你的主机上面跑了很多应用进程,那数据到了你这里,是不是要做一个进程到进程的区分?
  • 另外,也有非常重要的一个服务是把不可靠的通信变成可靠的通信

    • 网络层所提供的服务是不可靠的。前面我们也介绍过,在传输过程中可能丢包,可能错了,可能乱序,可能会重复。到了这里,把它变成可靠的通讯服务。
  • 🌰 传输层 TCP 见下面借助的是 IP 所提供的网络产品和服务。IP 提供服务是不可靠的,而 TCP 要把他变成可靠的。不出错,不重复,不丢失。

应用层

网络应用,为人类用户或者其他应用进程提供网络应用服务。比如淘宝、抖音等等等等,这些网络应用是网络存在的理由。

ISO/OSI 参考模型

然后除了互联网的 tcp ip 的五层参考模型之外,另外一种网络叫做 ISO/OSI 国际标准化组织 / 开放系统互联。

也有相应的参考模型,体系架构还有相应的一系列的标准。就是网络能分几层,每层主要功能体系架构指的是什么,就是在每一层当中有哪些协议。

它分成了七层,叫七重天,物理层,链路层,网络层,传输层,会话层,表示层,应用层。红色的部分是在 tcp ip 协议栈所没有的。

  • 表示层:允许应用解释传输的数据,e.g. 加密,压缩,机器相关的表示转换。

    • 应用进程之间传输的信息,不需要关心是怎么编码的,只用关心语义方面的信息。
  • 会话层:数据交换的同步,检查点,恢复

    • 就是会话管理,建立会话、维持会话 。

那在 tcp ip 协议栈在互联网体系架构当中,难道就没有一个表示转换和会话管理的需求吗?当然有,这些都是应用层自己去完成的。

封装和解封装

从源主机向另外一个主机发送报文。我是一个 web 的浏览器,你是 WEP 的客户端,我要发出一个请求给你。好像逻辑上来看,我可以直接向你发送报文,但直接是要打个引号的。

封装

  • 在应用层,message 能够直接传送给对方的应用进程吗?不可以。必须要通过层间的接口,借助下层所提供服务才能实现。
  • 交到传输层的时候,要加上他自己的控制信息,加上他自己的控制信息,然后形成本身的报文段。
  • 报文段再交给网络层,网络层要加上他自己的头部信息,包括什么的源IP、目标 IP 这样一些同步信息,形成分组。

    • 同步信息是本层形成的,加上上层 ICI 穿过层间接口的时候带来的信息。在网络层做一个转换,形成本层同步信息。
  • 到了链路层,再把分组加上链路层的头部可能还有尾部,形成一个帧交给物理层,
  • 物理层再把每一个比特,或者是若干比特形成一组,一组或者一个、一个地打出去。

解封装

  • 到对方的物理层,再还原成相应的链路层的帧。

    • 要判断哪些是帧的开始,哪些帧的结束,哪些帧的内容部分。物理层把帧取出来。
  • 链路层就知道帧的内容,包括帧头和数据部分。

    • 帧当中有目标 MAC 地址之类的一些信息,可以查询交换机的栈表和交换表,决定数据向哪里发送。
  • 然后端口再把它封装成其他链路的帧,再交给他的物理层,物理层再把正当中的每一个比特,在把它变成电磁波、光信号,打出去。
  • 到了下一跳,路由器插了几块网卡,每个网卡继承了链路层和物理层的功能。

    • 就是说我是一个路由器,我通过网卡接入到网,通过网卡和网相连。

      • 然后网卡说来了一个帧,我就把帧当中的数据部分取出来,帧当中携带的是上层、网络层的协议数据单元,就是分组。
  • 它有目标 IP 之类的控制信息,我再查询网络层的转发表,决定通过哪个网口把它放出去。
  • 我要把分组通过接口交给网卡,然后网卡再把它封装成帧,再把帧中的每个比特形成物理信号,把它打出去,又到了下一跳。
  • 这样一跳跳,最终可以到达目标主机。

    • 目标主机把网络层的物理层的每个 bit 取出来,然后把帧拿出来,真再把数据部分拿出来,形成分组。
  • 分组交给网络层,网络层再把分组的报文段拿出来,然后交给传输层。
  • 传输层把报文段拿到之后,把其中的 message 或者是 message 的一部分交给应用层。
  • 到了应用层,两个应用进程终于可以通信了。

所以说,

  • 在源端要做封装。
  • 在中间某个路由器或者交换机的时候,要做一个解封装、再封装。
  • 到了目标端要做一个大的解封装。

各层次的协议数据单元

各个层次的协议数据单元有一个规范。

  • 应用层:报文( message)
  • 传输层:报文段( segment):TCP段,UDP数据报
  • 网络层:分组 packet(如果无连接方式:数据报 datagram)
  • 数据链路层:帧( frame)
  • 物理层:位(bit)