转:网络详解

转自: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 协议总共有四层,就像搭积木一样,每一层需要下层的支撑,同时又支撑着上层,任何一层被抽掉都可能会导致整个协议栈坍塌。
image

第一层叫“链接层”(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 很像,从下到上分别是:

image

第一层:物理层,网络的物理形式,例如电缆、光纤、网卡、集线器等等;
第二层:数据链路层,它基本相当于 TCP/IP 的链接层;
第三层:网络层,相当于 TCP/IP 里的网际层;
第四层:传输层,相当于 TCP/IP 里的传输层;
第五层:会话层,维护网络中的连接状态,即保持会话和同步;
第六层:表示层,把数据转换为合适、可理解的语法和语义;
第七层:应用层,面向具体的应用传输数据。

TCP/IP 等协议已经在许多网络上实际运行,再推翻重来是不可能的。所以,OSI 分层模型在发布的时候就明确地表明是一个“参考”,不是强制标准。

但 OSI 模型也是有优点的。对比一下就可以看出,TCP/IP 是一个纯软件的栈,没有网络应有的最根基的电缆、网卡等物理设备的位置。而 OSI 则补足了这个缺失,在理论层面上描述网络更加完整。

还有一个重要的形式上的优点:OSI 为每一层标记了明确了编号,最底层是一层,最上层是七层,而 TCP/IP 的层次从来只有名字而没有编号。显然,在交流的时候说“七层”要比“应用层”更简单快捷,特别是英文,对比一下“Layer seven”与“application layer”。

1.2.3 两个分层模型的映射关系

image

第一层:物理层,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 协议,看到的只是一个可靠的传输链路,只要把数据加上自己的头,对方就能原样收到。
image

1.3 每层运行常见物理设备

image

2. 物理层

2.1 物理层的意义

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

2.2 集线器工作原理

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

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

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

由于转发到了所有出口,那 BCDE 四台机器怎么知道数据包是不是发给自己的呢?于是出现了数据链路层。

3. 数据链路层

3.1 数据链路层由来

数据链路层由来:单纯的0和1没有任何意义,必须规定电信号多少位一组,每组什么意思。
数据链路层的功能:定义了电信号的分组方式

3.2 以太网协议

早期的时候,每家公司都有自己的电信号分组方式。逐渐地,一种叫做"以太网"(Ethernet)的协议,占据了主导地位。
以太网规定:

  • 一组电信号构成一个数据包,叫做"帧"(Frame)。
  • 每一帧分成两个部分:标头(Head)和数据(Data)。

image

Head,固定为18字节,包含:

  • 发送者/源地址,6个字节
  • 接收者/目标地址,6个字节
  • 数据类型,6个字节

data,最短46字节,最长1500字节,包含:

  • 数据包的具体内容

head长度+data长度=最短64字节,最长1518字节,超过最大限制就分片发送

3.3 MAC地址

上面提到,Head包含了发送者和接受者的信息。以太网规定,连入网络的所有设备,都必须具有"网卡"。发送端和接收端的地址便是指网卡的地址,即mac地址。
image

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

image

3.4 广播

有了MAC地址,两台机器就可以进行通信了。以太网采用了一种很"原始"的方式,它不是把数据包准确送到接收方,而是向本网络内所有计算机发送,让每台计算机自己判断,是否为接收方,这就是广播。
A 在发送数据包给 B 时,头部Head包含了发送者和接受者的信息,B 在收到数据包后,根据头部的目标 MAC 地址判断这个数据包是发给自己的就收下。其他的 CDE 收到数据包后,根据头部的目标 MAC 地址判断这个数据包并不是发给自己的就丢弃
image

虽然集线器使整个布局干净不少,但原来我只要发给电脑 B 的消息,现在却要发给连接到集线器中的所有电脑,既不安全,又浪费网络资源。如果把这个集线器弄得更智能一些,只发给目标MAC地址的电脑,就好了。
image

3.5 交换机工作原理

虽然只比集线器多了这一点点区别,但看起来似乎有智能了,你把这东西叫做交换机。也正因为这一点点智能,你把它放在了另一个层级,数据链路层
image

交换机内部维护一张 MAC地址表,记录着每一个 MAC 地址的设备,连接在其哪一个端口上。假如你仍然要发给 B 一个数据包,到达交换机时,查找交换机内部的MAC地址表,发现B的MAC地址对应端口1,于是把数据从 1 号端口发给了 B,就结束了。

MAC地址表是如何建立的

  1. 最开始的时候,MAC地址表是空的。
  2. 现在A给B发送数据,由于这个包从端口 4 进入的交换机,所以此时交换机就可以在 MAC地址表记录第一条数据,MAC:aa-aa-aa-aa-aa-aa-aa端口:4。
  3. 交换机看目标MAC地址(bb-bb-bb-bb-bb-bb)在地址表中并没有映射关系,于是将此包发给了所有端口,也即发给了所有机器,只有机器B收到了确实是发给自己的包,于是做出了响应,响应数据从端口1进入交换机,于是交换机此时在地址表中更新了第二条数据,MAC:bb-bb-bb-bb-bb-bb端口:1。
  4. 经过该网络中的机器不断地通信,交换机最终将 MAC 地址表建立完毕。

3.6 交换机的局限

随着机器数量越多,交换机的端口也不够了,但只要将多个交换机连接起来,这个问题就轻而易举搞定。
image
你完全不需要设计额外的东西,按照上述的接线方式即可完成所有电脑的互联。但是要注意,上面那根红色的线在 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 与其端口的映射关系,就可以成功把数据包转交给路由器。

image

4. 网络层

4.1 网络层由来

4.1.1 为什么要划分子网?

有了以太网、MAC地址、广播的发送方式,理论上世界上的计算机就可以彼此通信了,问题是如果所有的通信都采用以太网的广播方式,那么一台机器发送的包全世界都会收到,这就不仅仅是效率低的问题了,这会是一种灾难。

必须将一个巨大的互联网拆分成无数个子网,让广播的范围减小,提高网络效率。必须找出一种方法来区分哪些计算机属于同一广播域,哪些不是,如果是就采用广播的方式发送,如果不是,就采用路由的方式(向不同广播域/子网分发数据包)。
image

4.1.2 为什么要引入IP地址?

MAC地址是无法区分的,它只跟厂商有关,与所处网络无关。如果你希望使用MAC 地址来区分网络,就需要某一子网下统统买一个厂商制造的设备,要么你就需要要求厂商在生产网络设备烧录 MAC 地址时,提前按照你规划好的子网结构来定 MAC 地址,并且日后这个网络的结构都不能轻易改变,这基本是不现实的。

这就导致了"网络层"的诞生。它的作用是引进一套新的地址,使得我们能够区分不同的计算机是否属于同一个子网络。这套地址就叫"网络地址"也叫做"IP地址"。MAC 地址一般是无法修改的,IP地址可以修改。

4.2 IP协议

  • 规定IP地址的协议叫IP协议,它定义的地址称之为IP地址,广泛采用的v4版本即ipv4,它规定网络地址由32位2进制表示。
  • 范围0.0.0.0-255.255.255.255。
  • 一个IP地址通常写成四段十进制数,例:172.16.10.1。
  • IP地址分成两个部分,【网络部分(区分不同子网),主机部分(区分子网中的主机)】。

image

4.2.1 IP数据包

根据IP协议发送的数据,就叫做IP数据包。IP数据包也分为head和data部分,无须为IP包定义单独的栏位,直接放入以太网包的data部分。这就是互联网分层结构的好处:上层的变动完全不涉及下层的结构。

  • head:长度为20到60字节
  • data:最长为65,515字节。

而以太网数据包的”数据”部分,最长只有1500字节。因此,如果IP数据包超过了1500字节,它就需要分割成几个以太网数据包,分开发送了。
image

4.3 路由器工作原理

我们先给上面的组网方式中的每一台设备,加上自己的 IP 地址
image

现在两个设备之间传输,除了加上数据链路层的头部之外,还要再增加一个网络层的头部。假如 A 给 B 发送数据,由于它们直接连着交换机,所以 A 直接发出如下数据包即可,其实网络层没有体现出作用。
image

但假如 A 给 C 发送数据,A 就需要先转交给路由器,然后再由路由器转交给 C。由于最底层的传输仍然需要依赖以太网,所以数据包是分成两段的。

A到路由器这段的包如下:
image

路由器到 C 这段的包如下:
image

好了,上面说的两种情况(A->B,A->C),相信细心的读者应该会有不少疑问,下面我们一个个来展开。

4.4 子网掩码

A 给 C 发数据包,怎么知道是否要通过路由器转发呢?

答案是子网,如果源IP与目的IP处于一个子网,数据包直接走交换机。不处于一个子网,就走路由器。现在只需要解决怎么判断源IP与目的IP处于一个子网就好了。

单纯的从IP地址无法判断,区分子网需要另一个参数"子网掩码"。子网掩码是表示子网络特征的一个参数,形式上等同于IP地址,也是一个32位二进制数字,它的网络部分全部为1,主机部分全部为0。例如网络长度是24的子网掩码就是11111111.11111111.11111111.00000000,写成十进制就是255.255.255.0。

收发双方两个IP地址与子网掩码分别进行AND运算(两个数位都为1,运算结果为1,否则为0),然后比较结果是否相同,如果是的话,就表明它们在同一个子网络中,否则就不是。

假如某台机器的子网掩码定为 255.255.255.0,比如:

  • A电脑:192.168.0.1 & 255.255.255.0 = 192.168.0.0
  • B电脑:192.168.0.2 & 255.255.255.0 = 192.168.0.0
  • C电脑:192.168.1.1 & 255.255.255.0 = 192.168.1.0
  • D电脑:192.168.1.2 & 255.255.255.0 = 192.168.1.0

那么 A 与 B 在同一个子网,C 与 D 在同一个子网,但是 A 与 C 就不在同一个子网,以此类推。所以如果 A 给 C 发消息, A 和 C 不在同一个子网,于是把包发给路由器。
image

4.5 默认网关

A如何知道,哪个设备是路由器?

答案是在A上要设置默认网关,A 只能直接把包发给同处于一个子网下的某个 IP 上,所以发给路由器还是发给某个电脑,对 A 来说也不关心,只要这个设备有个 IP 地址就行。所以默认网关,就是 A 在自己电脑里配置的一个 IP 地址,以便在发给不同子网的机器时,发给这个 IP 地址。
image

4.6 路由表

路由器如何知道C在哪?

答案是路由表,现在 A 要给 C 发数据包,已经成功发到路由器,路由器收到的数据包有目的 IP 也就是 C 的 IP 地址,需要转化成从自己的哪个端口出去,应该有个表,就像 MAC 地址表一样,这个表就叫路由表

不同于 MAC 地址表的是,路由表并不是一对一这种明确关系,我们下面看一个路由表的结构。

目的地址 子网掩码 下一跳 端口
192.168.0.0 255.255.255.0 0
192.168.0.254 255.255.255.255 0
192.168.1.0 255.255.255.0 1
192.168.1.254 255.255.255.255 1

由于子网掩码其实就表示前多少位是子网的网段,所以 192.168.0.0(255.255.255.0)可以简写为 192.168.0.0/24

目的地址 下一跳 端口
192.168.0.0/24 0
192.168.0.254/32 0
192.168.1.0/24 1
192.168.1.254/32 1

这个路由表就表示,192.168.0.xxx 这个子网下的,都转发到 0 号端口,192.168.1.xxx 这个子网下的,都转发到 1 号端口

4.7 ARP协议

上面说的都是 IP 层,但发送数据包的数据链路层需要知道 MAC 地址,可是我只知道 IP 地址该怎么办呢?

答案是ARP协议,可以根据IP地址找到MAC地址,同时机器上会有一张 ARP缓存表,表中记录着 IPMAC 地址的对应关系。

4.7.1 ARP协议工作原理

ARP协议使用广播的方式发送数据包,其中包含目标主机的IP地址,在目标主机MAC地址这一栏,填的是FF:FF:FF:FF:FF:FF,表示这是一个"广播"地址。

它所在子网络的每一台主机,都会收到这个数据包,如果目标IP地址与自身的IP地址相同就做出回复,向对方报告自己的MAC地址,否则就丢弃这个包。发送方和目标主机都可以更新本机的ARP缓存表。

这样通过大家不断广播ARP请求,最终所有电脑里面都将 arp 缓存表更新完整。

4.7.2 ARP协议介绍

ARP(Address Resolution Protocol)是一种网络协议,用于在IPv4网络中将IP地址解析为对应的MAC地址。在计算机网络中,每个设备都有唯一的MAC地址和IP地址。IP地址用于在网络层进行路由和寻址,而MAC地址用于在链路层进行设备间的通信。

当一个设备需要向另一个设备发送数据包时,它需要知道目标设备的MAC地址。ARP协议就是用来解决这个问题的。下面是ARP协议的基本工作流程:

  1. 当设备A知道目标设备B的IP地址但不知道对应的MAC地址时,设备A将发送一个ARP请求广播消息到本地网络。
  2. ARP请求消息中包含设备A的IP地址和MAC地址,以及设备A希望解析的目标IP地址。
  3. 所有收到ARP请求的设备都会检查请求中的目标IP地址是否与自己匹配。如果匹配,则该设备会将自己的MAC地址作为ARP响应发送回设备A。
  4. 设备A收到ARP响应后,会将目标设备B的IP地址与MAC地址进行映射,并将其缓存起来以备将来使用。
  5. 设备A现在知道了目标设备B的MAC地址,可以使用该地址发送数据包到目标设备B。

通过这种方式,ARP协议实现了将IP地址解析为对应的MAC地址,从而设备可以在本地网络中正确地进行通信。

需要注意的是,ARP协议在IPv4网络中使用,而在IPv6网络中使用的是邻居发现协议(Neighbor Discovery Protocol,NDP),它具有类似的功能但使用不同的协议机制。


如果设备B与设备A不在同一个子网(不在同一个局域网)中怎么办?

如果设备B与设备A不在同一个子网(不在同一个局域网)中,ARP协议通常无法直接找到设备B的MAC地址。这是因为ARP协议是基于局域网内的广播通信机制来解析IP地址和MAC地址的。

在不同子网的情况下,需要经过路由器(或者网络层设备)来进行通信。在这种情况下,通常会使用另一种协议,例如ARP的替代协议Proxy ARP代理。

ARP代理协议允许路由器(或网络层设备)在不同子网之间转发ARP请求和响应消息。当设备A需要与不在同一子网中的设备B通信时,设备A会向自己所在子网的默认网关(通常是路由器)发送ARP请求。路由器接收到ARP请求后,会根据自己的路由表将ARP请求转发到目标子网。设备B所在子网的设备会响应ARP请求,并将自己的MAC地址发送回路由器。路由器再将设备B的MAC地址发送回设备A,使得设备A可以与设备B进行通信。

因此,在不同子网的情况下,通过ARP代理协议或类似的协议,设备A可以间接地获取设备B的MAC地址。这个过程需要借助路由器或网络层设备的帮助来转发ARP请求和响应消息,以完成跨子网的通信。

4.7.3 Proxy ARP协议介绍

Proxy ARP(代理ARP)是一种网络协议,用于在不同子网之间转发ARP请求和响应。它允许一个网络设备(通常是路由器)代表其他设备响应ARP请求,并将源设备与目标设备之间的通信进行转发。

在一个网络中,当一个设备需要与另一个设备进行通信时,通常需要知道目标设备的MAC地址。在同一子网中,设备可以通过发送ARP请求广播来获取目标设备的MAC地址。然而,在不同子网之间,ARP广播无法直接到达目标设备,因为广播通常被限制在单个子网内。

这时,代理ARP就发挥作用了。当设备A位于子网A,而设备B位于子网B时,设备A发送ARP请求时,子网A的网关路由器(具备代理ARP功能)会代表设备B响应ARP请求,并将自己的MAC地址发送给设备A。然后,设备A就可以将数据包发送到网关路由器的MAC地址上,网关路由器再将数据包转发到子网B,使得设备A和设备B之间的通信得以实现。

代理ARP的使用可以使不同子网之间的通信更加灵活和方便,因为它允许设备绕过直接的ARP广播,利用代理设备转发ARP请求和响应。然而,需要注意的是,代理ARP只在IPv4网络中使用,而在IPv6网络中使用的是邻居发现协议(Neighbor Discovery Protocol,NDP)来实现类似的功能。

4.7.4 ARP是哪个层的协议

ARP(Address Resolution Protocol)是在计算机网络中工作在网络层(网络层也称为第三层)的协议。网络层是OSI模型和TCP/IP协议栈中的一个重要层级,负责处理数据的路由、寻址和转发。

ARP协议的主要功能是将IP地址解析为对应的MAC地址。当一个设备需要与网络中的另一个设备进行通信时,它需要知道目标设备的MAC地址才能正确发送数据帧。ARP协议允许设备通过广播查询目标设备的MAC地址,并在本地网络中进行地址解析。

具体而言,ARP协议在网络层中的位置如下:

  • 在OSI模型中,ARP协议工作在网络层(第三层)。它通过广播ARP请求来获取目标设备的MAC地址,从而实现数据包的正确发送和路由。
  • 在TCP/IP协议栈中,ARP协议也位于网络层。它与IP协议(Internet Protocol)配合使用,通过解析IP地址与MAC地址的映射关系,确保数据包能够在网络中正确地传递。

总结来说,ARP协议是在计算机网络的网络层(第三层)工作的协议。它在解析IP地址和MAC地址的映射关系上起着重要的作用,以便在网络中正确地寻址和路由数据。

5. 完整过程

A 给 F 发送一个数据包的整个过程是怎样的呢?
image

路由器 1 连接了路由器 2,所以其路由表有了下一跳地址这一个概念,所以它的路由表就变成了这个样子。如果匹配到了有下一跳地址的一项,则需要再次匹配,找到其端口,并找到下一跳 IP 的 MAC 地址。最终必须能映射到一个端口号,然后从这个端口号把数据包发出去。

目的地址 下一跳 端口
192.168.0.0/24 0
192.168.0.254/32 0
192.168.1.0/24 1
192.168.1.254/32 1
192.168.2.0/24 192.168.100.5
192.168.100.0/24 2
192.168.100.4/32 2

5.1 数据包流转详细过程

  1. A(192.168.0.1)通过子网掩码(255.255.255.0)计算出自己与 F(192.168.2.2)并不在同一个子网,于是决定将数据包发送给默认网关(192.168.0.254)。查看其 arp 缓存,找到 默认网关 192.168.0.254 的 MAC 地址(ABAB)将其封装在数据链路层头部,又将源 IP 地址(192.168.0.1)和目的 IP 地址(192.168.2.2)封装在网络层头部,然后发包。
    image
  2. 交换机 1 收到数据包后,发现目标 MAC 地址是 ABAB,将数据包发给路由器1。
  3. 路由器 1 收到数据包后,发现其目标 IP 地址是 192.168.2.2,查看其路由表,发现了下一跳的地址是192.168.100.5,再次匹配路由表,发现匹配到了端口为 2,查看其 arp 缓存,找到路由器2 192.168.100.5的MAC 地址为 D2D2,将其封装在数据链路层头部,并从 2 号端口把包发出去。
  4. 路由器 2 收到数据包后,发现其目标 IP 地址是 192.168.2.2,查询其路由表,匹配到端口号为 1,查看其 arp 缓存,找到目标IP 192.168.2.2的MAC 地址为 FFFF,将其封装在数据链路层头部,并从 1 号端口把包发出去。
  5. 交换机 3 收到了数据包,发现目的 MAC 地址为 FFFF,查询其 MAC 地址表,匹配到端口号为 6,于是从 6 号端口把数据包发出去。
  6. F 最终收到了数据包!并且发现目的 MAC 地址就是自己,于是收下了这个包。

6. 传输层

6.1 传输层由来

网络层的IP帮我们区分子网,以太网层的MAC帮我们找到主机,但是同一台主机上有许多程序进程,区分不同的程序需要一个新的参数端口,它其实就是给每一个进程的编号,每个数据包都发到主机的特定端口也就是特定的进程。

至此,发送的数据包上,增加了传输层的头部,源端口号与目标端口号。
image
端口范围0到65535,0-1023的端口被系统占用,用户只能用大于1023的端口。

"传输层"的功能,就是建立"端口到端口"的通信。相比之下,"网络层"的功能是建立"主机到主机"的通信。只要确定主机和端口,我们就能实现程序之间的交流。

6.2 UDP协议

现在,我们必须在数据包中加入端口信息,这就需要新的协议。最简单的实现叫做UDP协议。

UDP数据包非常简单,"标头"部分一共只有8个字节,总长度不超过65,535字节,正好能放进一个IP数据包。

6.3 TCP协议

UDP协议的优点是比较简单,容易实现,但是缺点是可靠性较差,一旦数据包发出,无法知道对方是否收到。有可能丢包。

为了解决这个问题,提高网络可靠性,TCP协议就诞生了。它就是有确认机制的UDP协议,每发出一个数据包都要求确认,一旦数据包遗失,就收不到确认,发出方就会重发。它的缺点是过程复杂、实现困难、消耗较多的资源。

TCP数据包和UDP数据包一样,都是内嵌在IP数据包的"数据"部分。TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会超过IP数据包的长度,以确保单个TCP数据包不必再分割。

7. 应用层

7.1 应用层由来

应用程序收到"传输层"的数据,接下来就要进行解读。由于互联网是开放架构,数据来源五花八门,必须事先规定好格式,否则根本无法解读。

"应用层"的作用,就是规定应用程序的数据格式。

TCP协议可以为各种各样的程序传递数据,比如Email、WWW、FTP等等。那么,必须有不同协议规定电子邮件、网页、FTP数据的格式,这些应用程序协议就构成了"应用层"。常见的应用层协议有http,ftp,smtp等。

这是最高的一层,直接面对用户。它的数据就放在TCP数据包的"数据"部分。因此,现在的以太网的数据包就变成下面这样。
image

7.2 ftp协议

FTP(File Transfer Protocol)协议,文件传输协议。提供交互式的访问,对传输文件的格式和类型有分类,允许文件具有存取权限。适合异构网络任意计算机的传送。

7.3 http协议

HTTP (HyperText Transfer Protocol),超文本传输协议,基于TCP/IP通信协议。是一种用于分布式、协作式和超媒体信息系统的应用层协议,是因特网上应用最为广泛的一种网络传输协议,所有的 WWW 文件都必须遵守这个标准。

7.4 socket

能够唯一标示网络中的进程后,它们就可以利用socket进行通信了,什么是socket呢?我们经常把socket翻译为套接字,socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。

socket起源于UNIX,在Unix一切皆文件哲学的思想下,socket是一种"打开—读/写—关闭"模式的实现,服务器和客户端各自维护一个"文件",在建立连接打开后,可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。

8. 访问网页

你买了一台新电脑,插上网线,开机,这时电脑能够上网吗?

通常你必须做一些设置。有时,管理员(或者ISP)会告诉你下面四个参数,你把它们填入操作系统,计算机就能连上网了:

  • 本机的IP地址
  • 子网掩码
  • 网关的IP地址
  • DNS的IP地址

下图是Windows系统的设置窗口,这四个参数缺一不可。
image

8.1 静态IP地址

由于它们是给定的,计算机每次开机,都会分到同样的IP地址,所以这种情况被称作"静态IP地址上网"。

但是,这样的设置很专业,普通用户望而生畏,而且如果一台电脑的IP地址保持不变,其他电脑就不能使用这个地址,不够灵活。出于这两个原因,大多数用户使用"动态IP地址上网"。

8.2 动态IP地址

所谓"动态IP地址",指计算机开机后,会自动分配到一个IP地址,不用人为设定。它使用的协议叫做DHCP协议。

8.3 DHCP协议

DHCP协议规定,每一个子网络中,有一台计算机负责管理本网络的所有IP地址,它叫做"DHCP服务器"。新的计算机加入网络,必须向"DHCP服务器"发送一个"DHCP请求"数据包,申请IP地址和相关的网络参数。

前面说过,如果两台计算机在同一个子网络,必须知道对方的MAC地址和IP地址,才能发送数据包。但是,新加入的计算机不知道这两个地址,怎么发送数据包呢?

8.3.1 DHCP协议数据包

首先,它是一种应用层协议,建立在UDP协议之上,所以整个数据包如下,DHCP协议做了一些巧妙的规定。
image

  • 以太网标头:设置发出方(本机)的MAC地址和接收方(DHCP服务器)的MAC地址。前者就是本机网卡的MAC地址,后者这时不知道,就填入一个广播地址:FF-FF-FF-FF-FF-FF。
  • IP标头:设置发出方的IP地址和接收方的IP地址。这时,对于这两者,本机都不知道。于是,发出方的IP地址就设为0.0.0.0,接收方的IP地址设为255.255.255.255。
  • UDP标头:设置发出方的端口68和接收方的端口67,这一部分是DHCP协议规定好的。

8.3.2 DHCP协议工作原理

  1. 以太网是广播发送数据包,同一个子网络的每台计算机都收到了这个包。因为接收方的MAC地址是FF-FF-FF-FF-FF-FF,看不出是发给谁的,必须继续分析这个包的IP地址,当看到发出方IP地址是0.0.0.0,接收方是255.255.255.255,于是DHCP服务器知道"这个包是发给我的",而其他计算机就可以丢弃这个包。
  2. DHCP服务器分配好IP地址后,响应一个"DHCP"数据包。这个响应包的结构也是类似的,以太网标头设置的MAC地址是双方的网卡地址,IP标头设置的发出方是DHCP服务器IP地址和接收方是255.255.255.255,UDP标头的设置发出方端口是67和接收方端口68,分配给请求端的IP地址和本网络的具体参数则包含在Data部分。
  3. 新加入的计算机收到这个响应包,判断出MAC地址和自己相符就收下此包,于是就知道了自己的IP地址、子网掩码、网关地址、DNS服务器等等参数。

8.4 DNS协议

8.4.1 DNS 是什么

互联网服务器多如牛毛,IP地址对于人类来说不方便记忆,于是发明了域名,例如www.baidu.com这是百度的域名。

8.4.2 域名的用途

代替IP地址:域名不仅能够代替 IP 地址,还有许多其他的用途。

虚拟主机:在 Apache、Nginx 这样的 Web 服务器里,域名可以用来标识虚拟主机,决定由哪个虚拟主机来对外提供服务。

命名系统:域名本质上还是个命名系统,使用多级域名就可以划分出不同的国家、地区、组织、公司、部门,每个域名都是独一无二的,可以作为一种身份的标识。比如 Java 的包机制就采用域名作为命名空间,只是用了反序。比如包名可能就是“com.example.www”。而 XML 里使用 URI 作为名字空间,也是间接使用了域名。

8.4.3 域名的层级

举例来说,www.example.com真正的域名是www.example.com.root,简写为www.example.com

根域名.root对于所有域名都是一样的,所以平时是省略的。

顶级域名:(top-level domain,缩写为TLD),比如.com.net

二级域名:(second-level domain,缩写为SLD),比如www.example.com里面的.example,这一级域名是用户可以注册的;

主机名:(host),比如www.example.com里面的www,又称为"三级域名",这是用户在自己的域里面为服务器分配的名称,是用户可以任意分配的。

总结一下,域名的层级结构如下。

主机名.次级域名.顶级域名.根域名
#即
host.sld.tld.root

8.4.4 域名解析

就像 IP 地址必须转换成 MAC 地址才能访问主机一样,域名也必须要转换成 IP 地址,这个过程就是“域名解析”。

目前全世界有几亿个站点,有几十亿网民,而每天网络上发生的 HTTP 流量更是天文数字。这些请求绝大多数都是基于域名来访问网站的,所以 DNS 就成了互联网的重要基础设施,必须要保证域名解析稳定可靠、快速高效。

DNS 的核心系统是一个三层的树状、分布式服务,基本对应域名的结构:

  1. 根域名服务器(Root DNS Server):管理顶级域名服务器,返回“com”“net”“cn”等顶级域名服务器的 IP 地址;
  2. 顶级域名服务器(Top-level DNS Server):管理各自域名下的权威域名服务器,比如com 顶级域名服务器可以返回 apple.com 域名服务器的 IP 地址;
  3. 权威域名服务器(Authoritative DNS Server):管理自己域名下主机的 IP 地址,比如apple.com 权威域名服务器可以返回 www.apple.com 的 IP 地址。
    image

在这里根域名服务器是关键,它必须是众所周知的,否则下面的各级服务器就无从谈起了。目前全世界共有 13 组根域名服务器,又有数百台的镜像,保证一定能够被访问到。

有了这个系统以后,任何一个域名都可以在这个树形结构里从顶至下进行查询,就好像是把域名从右到左顺序走了一遍,最终就获得了域名对应的 IP 地址。

例如,你要访问“www.apple.com”,就要进行下面的三次查询:

  1. 访问根域名服务器,它会告诉你“com”顶级域名服务器的地址;
  2. 访问“com”顶级域名服务器,它再告诉你“apple.com”域名服务器的地址;
  3. 最后访问“apple.com”域名服务器,就得到了“www.apple.com”的地址。

虽然核心的 DNS 系统遍布全球,服务能力很强也很稳定,但如果全世界的网民都往这个系统里挤,即使不挤瘫痪了,访问速度也会很慢。所以在核心 DNS 系统之外,还有两种手段用来减轻域名解析的压力,并且能够更快地获取结果,基本思路就是“缓存”。

首先,许多大公司、网络运行商都会建立自己的 DNS 服务器,作为用户 DNS 查询的代理,代替用户访问核心 DNS 系统。这些“野生”服务器被称为“非权威域名服务器”,可以缓存之前的查询结果,如果已经有了记录,就无需再向根服务器发起查询,直接返回对应的 IP 地址。

这些 DNS 服务器的数量要比核心系统的服务器多很多,而且大多部署在离用户很近的地方。比较知名的 DNS 有 Google 的“8.8.8.8”,Microsoft 的“4.2.2.1”,还有CloudFlare 的“1.1.1.1”等等。

以Chrome浏览器为例,一次DNS解析如下:

  1. Chrome浏览器会首先搜索浏览器自身的DNS缓存(缓存时间比较短,大概只有1分钟,且只能容纳1000条缓存),如果有且没有过期则解析结束。我们怎么查看Chrome自身的缓存?可以使用chrome://net-internals/#dns 来进行查看。
  2. 如果浏览器自身的缓存里面没有找到对应的条目,那么Chrome会搜索操作系统自身的DNS缓存,如果找到且没有过期则解析结束。怎么查看操作系统自身的DNS缓存?以Windows系统为例,可以在命令行下使用 ipconfig /displaydns 来进行查看。
  3. 如果操作系统的DNS缓存也没有找到,那么尝试读取hosts文件(wondows位于C:\Windows\System32\drivers\etc\hosts,linux位于/etc/hosts),如果找到解析结束。
  4. 如果在hosts文件中也没有找到对应的条目,浏览器就会发起一个DNS的系统调用,向本地配置的首选DNS服务器发起域名解析请求,DNS服务器首先查找自身的缓存,找到则解析结束。
  5. DNS服务器自身的缓存没有找到,则DNS服务器首先找到本机内置(几乎不会变更,所以是直接内置的)的13台根域名服务器的IP地址,再从"根域名服务器"查到"顶级域名服务器"IP地址,再从"顶级域名服务器"查到"次级域名服务器"IP地址,再从"次级域名服务器"查出"主机名"的IP地址,则解析结束。

下面的这张图比较完整地表示了现在的 DNS 架构:
image
在 Nginx 里有这么一条配置指令“resolver”,它就是用来配置 DNS 服务器的,如果没有它,那么 Nginx 就无法查询域名对应的 IP,也就无法反向代理到外部的网站。

resolver 8.8.8.8 valid=30s; # 指定 Google 的 DNS,缓存 30 秒

8.4.5 域名的新玩法

重定向:因为域名代替了 IP 地址,所以可以让对外服务的域名不变,而主机的 IP 地址任意变动。当主机有情况需要下线、迁移时,可以更改 DNS 记录,让域名指向其他的机器。

内部域名服务器:以可以使用 bind9 等开源软件搭建一个在内部使用的 DNS,这样我们开发的各种内部服务就都用域名来标记,比如数据库服务都用域名“mysql.inner.app”,商品服务都用“goods.inner.app”,发起网络通信时也就不必再使用写死的 IP 地址了,可以直接用域名。

负载均衡:1、因为域名解析可以返回多个 IP 地址,所以一个域名可以对应多台主机,客户端收到多个 IP 地址后,就可以自己使用轮询算法依次向服务器发起请求,实现负载均衡。2、域名解析可以配置内部的策略,返回离客户端最近的主机,或者返回当前服务质量最好的主机,这样在 DNS 端把请求分发到不同的服务器,实现负载均衡。

8.5 一个完整的访问网页的过程

  1. 在google浏览器输入一个域名回车。
  2. 浏览器先DNS域名解析成IP地址。
  3. 将请求信息封装成http数据包,发送给集线器,交换机,路由器最终到达网址对应IP的服务器。
  4. 服务器接收到请求,进行处理,将返回值封装成http数据包。
  5. 数据包经过集线器,交换机,路由器最终回到浏览器。
  6. 浏览器将返回的内容解析成网页内容呈现到你面前。
posted @ 2023-06-01 22:29  MyMemo  阅读(32)  评论(0编辑  收藏  举报