转:网络详解
转自:https://juejin.cn/post/7123028423827521543
1. 概述
1.1 协议
计算机之间通信是依靠互联网,互联网的核心是一系列协议。
协议,网络协议的简称,网络协议是通信计算机双方必须共同遵从的一组约定。如怎么样建立连接、怎么样互相识别等。它最终体现为在网络上传输的数据包的格式。
1.2 分层体系结构
协议往往分成几个层次进行定义,分层定义是为了层与层之间解耦,互不影响,职责清晰,提高兼容性,方便技术创新。
1.2.1 TCP/IP 网络分层模型(4层)
IP 协议是“Internet Protocol”的缩写,主要目的是解决寻址和路由问题,以及如何在两 点间传送数据包。IP 协议使用“IP 地址”的概念来定位互联网上的每一台计算机。
TCP 协议是“Transmission Control Protocol”的缩写,意思是“传输控制协议”,它位 于 IP 协议之上,基于 IP 协议提供可靠的、字节流形式的通信,是 HTTP 协议得以实现的基础。
TCP/IP 协议总共有四层,就像搭积木一样,每一层需要下层的支撑,同时又支撑着上层,任何一层被抽掉都可能会导致整个协议栈坍塌。

第一层叫“链接层”(link layer),负责在以太网、WiFi 这样的底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标记网络上的设备,所以有时候也叫 MAC层。MAC 层的传输单位是帧(frame)。
第二层叫“网际层”或者“网络互连层”(internet layer),IP 协议就处在这一层。因为IP 协议定义了“IP 地址”的概念,所以就可以在“链接层”的基础上,用 IP 地址取代MAC 地址,把许许多多的局域网、广域网连接成一个虚拟的巨大网络。IP 层的传输单位是包(packet)。
第三层叫“传输层”(transport layer),这个层次协议的职责是保证数据在 IP 地址标记的两点之间“可靠”地传输,是 TCP 协议工作的层次,另外还有它的一个“小伙伴”UDP。TCP 层的传输单位是段(segment)。TCP 是一个有状态的协议,需要先与对方建立连接然后才能发送数据,而且保证数据不丢失不重复。而 UDP 则比较简单,它无状态,不用事先建立连接就可以任意发送数据,但不保证数据一定会发到对方。两个协议的另一个重要区别在于数据的形式。TCP 的数据是连续的“字节流”,有先后顺序,而 UDP 则是分散的小数据包,是顺序发,乱序收。
第四层叫“应用层”(application layer),由于下面的三层把基础打得非常好,所以在这一层就“百花齐放”了,有各种面向具体应用的协议。例如 Telnet、SSH、FTP、SMTP 等等,当然还有我们的 HTTP。HTTP 的传输单位则是消息或报文message)。
1.2.2 OSI网络分层模型(7层)
OSI,全称是“开放式系统互联通信参考模型”(Open System Interconnection Reference Model)。
TCP/IP 发明于 1970 年代,当时除了它还有很多其他的网络协议,整个网络世界比较混乱。这个时候国际标准组织(ISO)注意到了这种现象,于是设计出了一个新的网络分层模型,想用这个新框架来统一既存的各种网络协议。
OSI 模型分成了七层,部分层次与 TCP/IP 很像,从下到上分别是:

第一层:物理层,网络的物理形式,例如电缆、光纤、网卡、集线器等等;
第二层:数据链路层,它基本相当于 TCP/IP 的链接层;
第三层:网络层,相当于 TCP/IP 里的网际层;
第四层:传输层,相当于 TCP/IP 里的传输层;
第五层:会话层,维护网络中的连接状态,即保持会话和同步;
第六层:表示层,把数据转换为合适、可理解的语法和语义;
第七层:应用层,面向具体的应用传输数据。
TCP/IP 等协议已经在许多网络上实际运行,再推翻重来是不可能的。所以,OSI 分层模型在发布的时候就明确地表明是一个“参考”,不是强制标准。
但 OSI 模型也是有优点的。对比一下就可以看出,TCP/IP 是一个纯软件的栈,没有网络应有的最根基的电缆、网卡等物理设备的位置。而 OSI 则补足了这个缺失,在理论层面上描述网络更加完整。
还有一个重要的形式上的优点:OSI 为每一层标记了明确了编号,最底层是一层,最上层是七层,而 TCP/IP 的层次从来只有名字而没有编号。显然,在交流的时候说“七层”要比“应用层”更简单快捷,特别是英文,对比一下“Layer seven”与“application layer”。
1.2.3 两个分层模型的映射关系

第一层:物理层,TCP/IP 里无对应;
第二层:数据链路层,对应 TCP/IP 的链接层;
第三层:网络层,对应 TCP/IP 的网际层;
第四层:传输层,对应 TCP/IP 的传输层;
第五、六、七层:统一对应到 TCP/IP 的应用层。
OSI 的分层模型在四层以上分的太细,而 TCP/IP 实际应用时的会话管理、编码转换、压缩等和具体应用经常联系的很紧密,很难分开。例如,HTTP 协议就同时包含了连接管理和数据格式定义。
所谓的“四层负载均衡”就是指工作在传输层上,基于 TCP/IP 协议的特性,例如 IP 地址、端口号等实现对后端服务器的负载均衡。
所谓的“七层负载均衡”就是指工作在应用层上,看到的是 HTTP 协议,解析 HTTP 报文里的 URI、主机名、资源类型等数据,再用适当的策略转发给后端服务器。
1.2.4 TCP/IP协议栈的工作方式
HTTP 协议的传输过程就是这样通过协议栈逐层向下,每一层都添加本层的专有数据,层层打包,然后通过下层发送出去。
接收数据是则是相反的操作,从下往上穿过协议栈,逐层拆包,每层去掉本层的专有头,上层就会拿到自己的数据。
下层的传输过程对于上层是完全“透明”的,上层也不需要关心下层的具体实现细节,所以就 HTTP 层次来看,它不管下层是不是 TCP/IP 协议,看到的只是一个可靠的传输链路,只要把数据加上自己的头,对方就能原样收到。

1.3 每层运行常见物理设备

2. 物理层
2.1 物理层的意义
电脑要通信,当然是先把电脑连起来,可以用光缆、电缆、双绞线、无线电波等方式。这就叫做"物理层",它就是把电脑连接起来的物理手段。它主要规定了网络的一些电气特性,作用是负责传送0和1的电信号。

2.2 集线器工作原理
网络上不可能只有两台机器在通信,这时候如果加入一台机器,就需要每台机器开两个网口,用一共三根网线,彼此相连。

随着越来越多的机器加入,你发现机器上开的网口越来越多,而且网线密密麻麻,混乱不堪,实际上一台电脑根本开不了这么多网口,所以这种连线只在理论上可行。

于是发明了一个中间设备,你们将网线都插到这个设备上,由这个设备做转发,就可以彼此之间通信了,本质上和原来一样,转换了一种形式,不再那么混乱。我们给它取名叫集线器,它仅仅是无脑将电信号转发到所有出口(广播),因此把集线器定性在了物理层。

由于转发到了所有出口,那 BCDE 四台机器怎么知道数据包是不是发给自己的呢?于是出现了数据链路层。
3. 数据链路层
3.1 数据链路层由来
数据链路层由来:单纯的0和1没有任何意义,必须规定电信号多少位一组,每组什么意思。
数据链路层的功能:定义了电信号的分组方式
3.2 以太网协议
早期的时候,每家公司都有自己的电信号分组方式。逐渐地,一种叫做"以太网"(Ethernet)的协议,占据了主导地位。
以太网规定:
- 一组电信号构成一个数据包,叫做"帧"(Frame)。
- 每一帧分成两个部分:标头(Head)和数据(Data)。

Head,固定为18字节,包含:
- 发送者/源地址,6个字节
- 接收者/目标地址,6个字节
- 数据类型,6个字节
data,最短46字节,最长1500字节,包含:
- 数据包的具体内容
head长度+data长度=最短64字节,最长1518字节,超过最大限制就分片发送
3.3 MAC地址
上面提到,Head包含了发送者和接受者的信息。以太网规定,连入网络的所有设备,都必须具有"网卡"。发送端和接收端的地址便是指网卡的地址,即mac地址。

每块网卡出厂的时候,都有一个全世界独一无二的MAC地址,长度是48个二进制位,通常用12个十六进制数表示。前6个十六进制数是厂商编号,后6个是该厂商的网卡流水号。有了MAC地址,就可以定位网卡和数据包的路径了。

3.4 广播
有了MAC地址,两台机器就可以进行通信了。以太网采用了一种很"原始"的方式,它不是把数据包准确送到接收方,而是向本网络内所有计算机发送,让每台计算机自己判断,是否为接收方,这就是广播。
A 在发送数据包给 B 时,头部Head包含了发送者和接受者的信息,B 在收到数据包后,根据头部的目标 MAC 地址判断这个数据包是发给自己的就收下。其他的 CDE 收到数据包后,根据头部的目标 MAC 地址判断这个数据包并不是发给自己的就丢弃。
虽然集线器使整个布局干净不少,但原来我只要发给电脑 B 的消息,现在却要发给连接到集线器中的所有电脑,既不安全,又浪费网络资源。如果把这个集线器弄得更智能一些,只发给目标MAC地址的电脑,就好了。
3.5 交换机工作原理
虽然只比集线器多了这一点点区别,但看起来似乎有智能了,你把这东西叫做交换机。也正因为这一点点智能,你把它放在了另一个层级,数据链路层。

交换机内部维护一张 MAC地址表,记录着每一个 MAC 地址的设备,连接在其哪一个端口上。假如你仍然要发给 B 一个数据包,到达交换机时,查找交换机内部的MAC地址表,发现B的MAC地址对应端口1,于是把数据从 1 号端口发给了 B,就结束了。
MAC地址表是如何建立的
- 最开始的时候,MAC地址表是空的。
- 现在A给B发送数据,由于这个包从端口 4 进入的交换机,所以此时交换机就可以在 MAC地址表记录第一条数据,MAC:aa-aa-aa-aa-aa-aa-aa端口:4。
- 交换机看目标MAC地址(bb-bb-bb-bb-bb-bb)在地址表中并没有映射关系,于是将此包发给了所有端口,也即发给了所有机器,只有机器B收到了确实是发给自己的包,于是做出了响应,响应数据从端口1进入交换机,于是交换机此时在地址表中更新了第二条数据,MAC:bb-bb-bb-bb-bb-bb端口:1。
- 经过该网络中的机器不断地通信,交换机最终将 MAC 地址表建立完毕。
3.6 交换机的局限
随着机器数量越多,交换机的端口也不够了,但只要将多个交换机连接起来,这个问题就轻而易举搞定。

你完全不需要设计额外的东西,按照上述的接线方式即可完成所有电脑的互联。但是要注意,上面那根红色的线在 MAC 地址表中可不是一条记录,而是要把 EFGH 这四台机器与该端口(端口6)的映射全部记录在表中。最终,两个交换机将分别记录 A ~ H 所有机器的映射记录。
左边的交换机
| MAC 地址 | 端口 |
|---|---|
| bb-bb-bb-bb-bb-bb | 1 |
| cc-cc-cc-cc-cc-cc | 3 |
| aa-aa-aa-aa-aa-aa | 4 |
| dd-dd-dd-dd-dd-dd | 5 |
| ee-ee-ee-ee-ee-ee | 6 |
| ff-ff-ff-ff-ff-ff | 6 |
| gg-gg-gg-gg-gg-gg | 6 |
| hh-hh-hh-hh-hh-hh | 6 |
右边的交换机
| MAC 地址 | 端口 |
|---|---|
| bb-bb-bb-bb-bb-bb | 1 |
| cc-cc-cc-cc-cc-cc | 1 |
| aa-aa-aa-aa-aa-aa | 1 |
| dd-dd-dd-dd-dd-dd | 1 |
| ee-ee-ee-ee-ee-ee | 2 |
| ff-ff-ff-ff-ff-ff | 3 |
| gg-gg-gg-gg-gg-gg | 4 |
| hh-hh-hh-hh-hh-hh | 6 |
这在只有 8 台电脑甚至只有几百台电脑的时候,都还好,所以这种交换机的设计方式,已经足足支撑一阵子了。但很遗憾,电脑的数量很快就发展到几万,几十万,几百万。交换机已经无法记录如此庞大的映射关系了。
问题的根本在于,连出去的那根红色的网线,后面不知道有多少个设备不断地连接进来,从而使得MAC地址表越来越大,不可控。那我可不可以让那根红色的网线,接入一个新的设备,这个设备就跟电脑一样有自己独立的 MAC 地址,而且同时还能帮我把数据包做一次转发,这样,一个端口对应的MAC就会固定成一个,MAC地址表的大小就是可控的。
这个设备就是路由器,它的功能就是,作为一台独立的拥有MAC地址的设备,并且可以把数据包做一次转发,把它定在了网络层。
路由器的每一个端口,都有独立的 MAC 地址。现在交换机的MAC地址表中,只需要多出一条MAC地址 ABAB 与其端口的映射关系,就可以成功把数据包转交给路由器。

4. 网络层
4.1 网络层由来
4.1.1 为什么要划分子网?
有了以太网、MAC地址、广播的发送方式,理论上世界上的计算机就可以彼此通信了,问题是如果所有的通信都采用以太网的广播方式,那么一台机器发送的包全世界都会收到,这就不仅仅是效率低的问题了,这会是一种灾难。
必须将一个巨大的互联网拆分成无数个子网,让广播的范围减小,提高网络效率。必须找出一种方法来区分哪些计算机属于同一广播域,哪些不是,如果是就采用广播的方式发送,如果不是,就采用路由的方式(向不同广播域/子网分发数据包)。

4.1.2 为什么要引入IP地址?
MAC地址是无法区分的,它只跟厂商有关,与所处网络无关。如果你希望使用MAC 地址来区分网络,就需要某一子网下统统买一个厂商制造的设备,要么你就需要要求厂商在生产网络设备烧录 MAC 地址时,提前按照你规划好的子网结构来定 MAC 地址,并且日后这个网络的结构都不能轻易改变,这基本是不现实的。
这就导致了"网络层"的诞生。它的作用是引进一套新的地址,使得我们能够区分不同的计算机是否属于同一个子网络。这套地址就叫"网络地址"也叫做"IP地址"。MAC 地址一般是无法修改的,IP地址可以修改。