diff --git a/src/.vuepress/sidebar/zh.ts b/src/.vuepress/sidebar/zh.ts index b10ffe0..d0c1630 100644 --- a/src/.vuepress/sidebar/zh.ts +++ b/src/.vuepress/sidebar/zh.ts @@ -314,8 +314,28 @@ export const zhSidebar = sidebar({ icon: "github", text: "九、开源推荐", prefix: "opensource/", - children: "structure", collapsible: true, + children: "structure" + }, + { + icon: "xiayu", + text: "十、技术琐碎", + collapsible: true, + prefix: "rain/", + children: [ + { + icon: "clash", + text: "Clash", + prefix: "clash", + collapsible: true, + children: [ + "Openclash" + ], + }, + "1.VPN", + "2.Soft Router Prerequisite Home Network Communication", + "3.Side Router" + ] }, ], "/life/": [ diff --git a/src/.vuepress/theme.ts b/src/.vuepress/theme.ts index 9f42513..52e7c2f 100644 --- a/src/.vuepress/theme.ts +++ b/src/.vuepress/theme.ts @@ -11,7 +11,7 @@ export default hopeTheme({ }, // iconAssets: 'iconfont', - iconAssets: '//at.alicdn.com/t/c/font_4791007_akxvrehyr4g.css', + iconAssets: '//at.alicdn.com/t/c/font_4791007_j1e8hdhzv8.css', logo: '/logo.svg', diff --git a/src/frontend/react/images/image-20220414083224689.webp b/src/frontend/react/images/image-20220414083224689.webp deleted file mode 100644 index a9ab22d..0000000 Binary files a/src/frontend/react/images/image-20220414083224689.webp and /dev/null differ diff --git a/src/frontend/react/images/image-20220605230344345.webp b/src/frontend/react/images/image-20220605230344345.webp deleted file mode 100644 index 63a3d3b..0000000 Binary files a/src/frontend/react/images/image-20220605230344345.webp and /dev/null differ diff --git a/src/fundamental/network/4.If you were to design a network copy.md b/src/fundamental/network/4.If you were to design a network copy.md new file mode 100644 index 0000000..fdedd01 --- /dev/null +++ b/src/fundamental/network/4.If you were to design a network copy.md @@ -0,0 +1,453 @@ +--- +order: 4 +author: +title: "如果让你来设计网络?" +category: + - 计网 + - 路由器 + - 交换机 + +--- + +:::tip +转载自 [飞天闪客: 如果让你来设计网络](https://mp.weixin.qq.com/s/N8a-YcCoVmXNrDWjnaxuJg)。 +::: + +**你是一台电脑,你的名字叫 A** + +很久很久之前,你不与任何其他电脑相连接,孤苦伶仃。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185009653-1039741158.png) + +直到有一天,你希望与另一台电脑 B 建立通信,于是你们各开了一个网口,用一根**网线**连接了起来。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185010813-1181741890.png) + +用一根网线连接起来怎么就能"通信"了呢?我可以给你讲 IO、讲中断、讲缓冲区,但这不是研究网络时该关心的问题。 + +如果你纠结,要么去研究一下操作系统是如何处理网络 IO 的,要么去研究一下包是如何被网卡转换成电信号发送出去的,要么就仅仅把它当做电脑里有个小人在**开枪**吧~ + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185011303-1016594752.gif) + +反正,你们就是连起来了,并且可以通信。 + +**第一层** + +有一天,一个新伙伴 C 加入了,但聪明的你们很快发现,可以每个人开**两个网口**,用一共**三根网线**,彼此相连。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185012021-1922348067.png) + +随着越来越多的人加入,你发现身上开的网口实在太多了,而且网线密密麻麻,混乱不堪。(而实际上一台电脑根本开不了这么多网口,所以这种连线只在理论上可行,所以连不上的我就用红色虚线表示了,就是这么严谨哈哈~) + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185012544-149916975.png) + +于是你们发明了一个中间设备,你们将网线都插到这个设备上,由这个设备做转发,就可以彼此之间通信了,本质上和原来一样,只不过网口的数量和网线的数量减少了,不再那么混乱。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185013190-1868258890.png) + +你给它取名叫**集线器**,它仅仅是无脑将电信号**转发到所有出口(广播)** ,不做任何处理,你觉得它是没有智商的,因此把人家定性在了**物理层**。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185015454-31905931.gif) + +由于转发到了所有出口,那 BCDE 四台机器怎么知道数据包是不是发给自己的呢? + +首先,你要给所有的连接到集线器的设备,都起个名字。原来你们叫 ABCD,但现在需要一个更专业的,**全局唯一**的名字作为标识,你把这个更高端的名字称为 **MAC 地址**。 + +你的 MAC 地址是 aa-aa-aa-aa-aa-aa,你的伙伴 b 的 MAC 地址是 bb-bb-bb-bb-bb-bb,以此类推,不重复就好。 + +这样,A 在发送数据包给 B 时,只要在头部拼接一个这样结构的数据,就可以了。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185022142-1152116486.png) + +B 在收到数据包后,根据头部的目标 MAC 地址信息,判断这个数据包的确是发给自己的,于是便**收下**。 + +其他的 CDE 收到数据包后,根据头部的目标 MAC 地址信息,判断这个数据包并不是发给自己的,于是便**丢弃**。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185018302-1214455092.gif) + +虽然集线器使整个布局干净不少,但原来我只要发给电脑 B 的消息,现在却要发给连接到集线器中的所有电脑,这样既不安全,又不节省网络资源。 + +**第二层** + +如果把这个集线器弄得更智能一些,**只发给目标 MAC 地址指向的那台电脑**,就好了。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185020647-1203400301.gif) + +虽然只比集线器多了这一点点区别,但看起来似乎有智能了,你把这东西叫做**交换机**。也正因为这一点点智能,你把它放在了另一个层级,**数据链路层**。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185021400-424840260.png) + +如上图所示,你是这样设计的。 + +交换机内部维护一张 **MAC 地址表**,记录着每一个 MAC 地址的设备,连接在其哪一个端口上。 + +| 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 | + +假如你仍然要发给 B 一个数据包,构造了如下的数据结构从网口出去。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185022142-1152116486.png) + +到达交换机时,交换机内部通过自己维护的 MAC 地址表,发现**目标机器 B 的 MAC 地址 bb-bb-bb-bb-bb-bb 映射到了端口 1 上**,于是把数据从 1 号端口发给了 B,完事~ + +你给这个通过这样传输方式而组成的小范围的网络,叫做**以太网**。 + +当然最开始的时候,MAC 地址表是空的,是怎么逐步建立起来的呢? + +假如在 MAC 地址表为空是,你给 B 发送了如下数据 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185022142-1152116486.png) + +由于这个包从端口 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** + +过程如下 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185030511-1489311259.gif) + +经过该网络中的机器不断地通信,交换机最终将 MAC 地址表建立完毕~ + +随着机器数量越多,交换机的端口也不够了,但聪明的你发现,只要将多个交换机连接起来,这个问题就轻而易举搞定~ + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185033173-254027488.png) + +你完全不需要设计额外的东西,只需要按照之前的设计和规矩来,按照上述的接线方式即可完成所有电脑的互联,所以交换机设计的这种规则,真的很巧妙。你想想看为什么(比如 A 要发数据给 F)。 + +但是你要注意,上面那根红色的线,最终在 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 地址的设备,并且可以帮我把数据包做一次转发 **,** 你把它定在了**网络层。** + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185035712-1222805156.png) + +注意,路由器的每一个端口,都有独立的 MAC 地址 + +好了,现在交换机的 MAC 地址表中,只需要多出一条 MAC 地址 ABAB 与其端口的映射关系,就可以成功把数据包转交给路由器了,这条搞定。 + +那如何做到,把发送给 C 和 D,甚至是把发送给 DEFGH.... 的数据包,统统先发送给路由器呢? + +不难想到这样一个点子,假如电脑 C 和 D 的 MAC 地址拥有共同的前缀,比如分别是 + +**C 的 MAC 地址:FFFF-FFFF-CCCC** + +**D 的 MAC 地址:FFFF-FFFF-DDDD** + +那我们就可以说,将目标 MAC 地址为 **FFFF-FFFF-?开头的**,统统先发送给路由器。这样是否可行呢?答案是否定的。 + +我们先从现实中 MAC 地址的结构入手,MAC地址也叫物理地址、硬件地址,长度为 48 位,一般这样来表示 + +**00-16-EA-AE-3C-40** + +它是由网络设备制造商生产时烧录在网卡的EPROM(一种闪存芯片,通常可以通过程序擦写)。其中**前 24 位(00-16-EA)代表网络硬件制造商的编号,后 24 位(AE-3C-40)是该厂家自己分配的,一般表示系列号。** 只要不更改自己的 MAC 地址,MAC 地址在世界是唯一的。形象地说,MAC地址就如同身份证上的身份证号码,具有唯一性。 + +那如果你希望向上面那样表示将目标 MAC 地址为 **FFFF-FFFF-?开头的**,统一从路由器出去发给某一群设备(后面会提到这其实是子网的概念),那你就需要要求某一子网下统统买一个厂商制造的设备,要么你就需要要求厂商在生产网络设备烧录 MAC 地址时,提前按照你规划好的子网结构来定 MAC 地址,并且日后这个网络的结构都不能轻易改变。 + +这显然是不现实的。 + +于是你发明了一个新的地址,给每一台机器一个 32 位的编号,如: + +**11000000101010000000000000000001** + +你觉得有些不清晰,于是把它分成四个部分,中间用点相连。 + +**11000000.10101000.00000000.00000001** + +你还觉得不清晰,于是把它转换成 10 进制。 + +**192.168.0.1** + +最后你给了这个地址一个响亮的名字,**IP 地址**。现在每一台电脑,同时有自己的 MAC 地址,又有自己的 IP 地址,只不过 IP 地址是**软件层面**上的,可以随时修改,MAC 地址一般是无法修改的。 + +这样一个可以随时修改的 IP 地址,就可以根据你规划的网络拓扑结构,来调整了。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185036228-204542799.png) + +如上图所示,假如我想要发送数据包给 ABCD 其中一台设备,不论哪一台,我都可以这样描述, **"将 IP 地址为 192.168.0 开头的全部发送给到路由器,之后再怎么转发,交给它!"** ,巧妙吧。 + +那交给路由器之后,路由器又是怎么把数据包准确转发给指定设备的呢? + +别急我们慢慢来。 + +我们先给上面的组网方式中的每一台设备,加上自己的 IP 地址 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185036771-1849644373.png) + +现在两个设备之间传输,除了加上数据链路层的头部之外,还要再增加一个网络层的头部。 + +假如 A 给 B 发送数据,由于它们直接连着交换机,所以 A 直接发出如下数据包即可,其实网络层没有体现出作用。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185037423-771296534.png) + +但假如 A 给 C 发送数据,A 就需要先转交给路由器,然后再由路由器转交给 C。由于最底层的传输仍然需要依赖以太网,所以数据包是分成两段的。 + +A ~ 路由器这段的包如下: + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185038155-466094322.png) + +路由器到 C 这段的包如下: + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185039134-888778403.png) + +好了,上面说的两种情况(A->B,A->C),相信细心的读者应该会有不少疑问,下面我们一个个来展开。 + +‍ + +> **A 给 C 发数据包,怎么知道是否要通过路由器转发呢?** + +**答案:子网** + +如果源 IP 与目的 IP 处于一个子网,直接将包通过交换机发出去。 + +如果源 IP 与目的 IP 不处于一个子网,就交给路由器去处理。 + +好,那现在只需要解决,什么叫处于一个子网就好了。 + +- 192.168.0.1 和 192.168.0.2 处于同一个子网 +- 192.168.0.1 和 192.168.1.1 处于不同子网 + +这两个是我们人为规定的,即我们想表示,对于 192.168.0.1 来说: + +**192.168.0.xxx 开头的,就算是在一个子网,否则就是在不同的子网。** + +那对于计算机来说,怎么表达这个意思呢?于是人们发明了**子网掩码**的概念 + +假如某台机器的子网掩码定为 255.255.255.0 + +这表示,将源 IP 与目的 IP 分别同这个子网掩码进行**与运算,相等则是在一个子网,不相等就是在不同子网**,就这么简单。 + +比如 + +- **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 就不在同一个子网,与 D 也不在同一个子网,以此类推。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185040262-2081870527.png) + +所以如果 A 给 C 发消息,A 和 C 的 IP 地址分别 & A 机器配置的子网掩码,发现不相等,则 A 认为 C 和自己不在同一个子网,于是把包发给路由器,就不管了,**之后怎么转发,A 不关心**。 + +> **A 如何知道,哪个设备是路由器?** + +**答案:在 A 上要设置默认网关** + +上一步 A 通过是否与 C 在同一个子网内,判断出自己应该把包发给路由器,那路由器的 IP 是多少呢? + +其实说发给路由器不准确,应该说 A 会把包发给**默认网关**。 + +对 A 来说,A 只能**直接**把包发给同处于一个子网下的某个 IP 上,所以发给路由器还是发给某个电脑,对 A 来说也不关心,只要这个设备有个 IP 地址就行。 + +所以**默认网关,就是 A 在自己电脑里配置的一个 IP 地址**,以便在发给不同子网的机器时,发给这个 IP 地址。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185040981-1432901837.png) + +仅此而已! + +> **路由器如何知道C在哪里?** + +**答案:路由表** + +现在 A 要给 C 发数据包,已经可以成功发到路由器这里了,最后一个问题就是,**路由器怎么知道,收到的这个数据包,该从自己的哪个端口出去**,才能直接(或间接)地最终到达目的地 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 号端口**。下一跳列还没有值,我们先不管 + +配合着结构图来看(这里把子网掩码和默认网关都补齐了)图中 & 笔误,结果应该是 .0 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185115306-322088421.gif) + +> **刚才说的都是 IP 层,但发送数据包的数据链路层需要知道 MAC 地址,可是我只知道 IP 地址该怎么办呢?** + +**答案:arp** + +假如你(A)此时**不知道**你同伴 B 的 MAC 地址(现实中就是不知道的,刚刚我们只是假设已知),你只知道它的 IP 地址,你该怎么把数据包准确传给 B 呢? + +答案很简单,在网络层,**我需要把 IP 地址对应的 MAC 地址找到**,也就是通过某种方式,找到 **192.168.0.2** 对应的 MAC 地址 **BBBB**。 + +这种方式就是 **arp 协议**,同时电脑 A 和 B 里面也会有一张 **arp 缓存表**,表中记录着 **IP 与 MAC 地址**的对应关系。 + +| IP 地址 | MAC 地址 | +| :---------: | :------: | +| 192.168.0.2 | BBBB | + +一开始的时候这个表是**空的**,电脑 A 为了知道电脑 B(192.168.0.2)的 MAC 地址,将会**广播**一条 arp 请求,B 收到请求后,带上自己的 MAC 地址给 A 一个**响应**。此时 A 便更新了自己的 arp 表。 + +这样通过大家不断广播 arp 请求,最终所有电脑里面都将 arp 缓存表更新完整。 + +**总结一下** + +好了,总结一下,到目前为止就几条规则 + +**从各个节点的视角来看** + +**电脑视角:** + +- 首先我要知道我的 IP 以及对方的 IP +- 通过子网掩码判断我们是否在同一个子网 +- 在同一个子网就通过 arp 获取对方 mac 地址直接扔出去 +- 不在同一个子网就通过 arp 获取默认网关的 mac 地址直接扔出去 + +**交换机视角:** + +- 我收到的数据包必须有目标 MAC 地址 +- 通过 MAC 地址表查映射关系 +- 查到了就按照映射关系从我的指定端口发出去 +- 查不到就所有端口都发出去 + +**路由器视角:** + +- 我收到的数据包必须有目标 IP 地址 +- 通过路由表查映射关系 +- 查到了就按照映射关系从我的指定端口发出去(不在任何一个子网范围,走其路由器的默认网关也是查到了) +- 查不到则返回一个路由不可达的数据包 + +如果你嗅觉足够敏锐,你应该可以感受到下面这句话: + +网络层(IP协议)本身没有传输包的功能,包的实际传输是委托给数据链路层(以太网中的交换机)来实现的。 + +**涉及到的三张表分别是** + +- 交换机中有 **MAC 地址**表用于映射 MAC 地址和它的端口 +- 路由器中有**路由表**用于映射 IP 地址(段)和它的端口 +- 电脑和路由器中都有 **arp 缓存表**用于缓存 IP 和 MAC 地址的映射关系 + +**这三张表是怎么来的** + +- MAC 地址表是通过以太网内各节点之间不断通过交换机通信,不断完善起来的。 +- 路由表是各种路由算法 + 人工配置逐步完善起来的。 +- arp 缓存表是不断通过 arp 协议的请求逐步完善起来的。 + +知道了以上这些,目前网络上两个节点是如何发送数据包的这个过程,就完全可以解释通了! + +那接下来我们就放上本章 **最后一个** 网络拓扑图吧,请做好 **战斗** 准备! + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185120860-2032025412.png) + +这时路由器 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 | + +**这时如果 A 给 F 发送一个数据包,能不能通呢?如果通的话整个过程是怎样的呢?** + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185122743-1665597384.png) + +**详细过程动画描述:** + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185152701-1748702521.gif) + +**详细过程文字描述:** + +**1.** 首先 A(192.168.0.1)通过子网掩码(255.255.255.0)计算出自己与 F(192.168.2.2)并不在同一个子网内,于是决定发送给默认网关(192.168.0.254) + +**2.** A 通过 ARP 找到 默认网关 192.168.0.254 的 MAC 地址。 + +**3.** A 将源 MAC 地址(AAAA)与网关 MAC 地址(ABAB)封装在数据链路层头部,又将源 IP 地址(192.168.0.1)和目的 IP 地址(192.168.2.2)(注意这里千万不要以为填写的是默认网关的 IP 地址,从始至终这个数据包的两个 IP 地址都是不变的,只有 MAC 地址在不断变化)封装在网络层头部,然后发包 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185156317-1265081814.png) + +**4.** 交换机 1 收到数据包后,发现目标 MAC 地址是 ABAB,转发给路由器1 + +**5.** 数据包来到了路由器 1,发现其目标 IP 地址是 192.168.2.2,查看其路由表,发现了下一跳的地址是 192.168.100.5 + +**6.** 所以此时路由器 1 需要做两件事,第一件是再次匹配路由表,发现匹配到了端口为 2,于是将其封装到数据链路层,最后把包从 2 号口发出去。 + +**7.** 此时路由器 2 收到了数据包,看到其目的地址是 192.168.2.2,查询其路由表,匹配到端口号为 1,准备从 1 号口把数据包送出去。 + +**8.** 但此时路由器 2 需要知道 192.168.2.2 的 MAC 地址了,于是查看其 arp 缓存,找到其 MAC 地址为 FFFF,将其封装在数据链路层头部,并从 1 号端口把包发出去。 + +**9.** 交换机 3 收到了数据包,发现目的 MAC 地址为 FFFF,查询其 MAC 地址表,发现应该从其 6 号端口出去,于是从 6 号端口把数据包发出去。 + +**10.** **F 最终收到了数据包!** 并且发现目的 MAC 地址就是自己,于是收下了这个包 + +‍ + +**后记** + +至此,经过物理层、数据链路层、网络层这前三层的协议,以及根据这些协议设计的各种网络设备(网线、集线器、交换机、路由器),理论上只要拥有对方的 IP 地址,就已经将地球上任意位置的两个节点连通了。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/1880627-20241116185157546-1751617760.png) + diff --git a/src/fundamental/network/5.Soft Router Prerequisite Home Network Communication.md b/src/fundamental/network/5.Soft Router Prerequisite Home Network Communication.md new file mode 100644 index 0000000..9b85eef --- /dev/null +++ b/src/fundamental/network/5.Soft Router Prerequisite Home Network Communication.md @@ -0,0 +1,119 @@ +--- +order: 5 +author: +title: "软路由前提篇:家庭网络通信" +category: + - 计网 + - 路由器 + - 交换机 + - DHCP DNS ARP + +--- + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/image-20250116011641002.png) + +### 1. **家庭网络的基本设置** + +你在运营商拉了一条宽带,运营商会给你分配一个光猫。你通常会单独再买一台路由器,使用网线将路由器的 WAN 口与光猫相连。通常情况下,颜色不一样的接口就是路由器的WAN口。路由器通过 PPPoE 拨号获取运营商分配的公网 IP(假设为 `2.2.2.2`),或者光猫负责拨号,路由器获取内网 IP(如 `192.168.0.2`)。 + +总之不管怎样,你的路由器WAN口会获取到一个IP。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/image-20250116012735730.png) + +除了WAN口,路由器还有多个颜色一样的LAN口,为了让大家思路清晰,我们需要单独提取出这4个LAN口,把它当做一台交换机,并且和路由器这个虚拟的网口`LAN`建立了连接,路由器连接交换机的这个网口有一个IP地址,假设为`192.168.1.1`,这个是路由器的内网IP。 + +访问这个IP可以进入路由器的**管理页面**,同时也是你家里整个局域网的网关,你家里所有的网络设备,都会通过网线或者WIFI的方式,连接到这台交换机,这是大部分家庭的网络拓扑,装宽带的师傅会帮你配置好,确保你能正常上网。 + +路由器的虚拟LAN口连接交换机,交换机连接家中的其他设备(如电脑、手机等)。路由器的内网 IP 通常是 `192.168.1.1`,这是局域网的网关。 + +------ + +### 2. **电脑获取 IP 地址(DHCP 协议)** + +当电脑通过网线或 Wi-Fi 连接到网络时,会通过 DHCP(动态主机配置协议)自动获取 IP 地址。 + +电脑的 DHCP 客户端(**操作系统内置了**)会发起一个 DHCP 请求,找DHCP服务器获取IP地址,这个请求会被一层层的封装。 + +以TCP/IP四层网络模型为例,每一层都有其特定的任务。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/image-20250116130747581.png) + +==数据来到传输层==,传输层会指定这个DHCP请求-通过什么传输协议发往什么端口。DHCP规定客户端默认使用68号UDP端口,服务端默认使用67号UDP端口,也就是请求会使用UDP的68号端口发往UDP的67号端口,所以源端口是68,目标端口是67,使用UDP的方式传输,这些都是规定好的。 + +==接着数据来到网络层==,网络层需要确定,数据包发给哪个网络设备,也就是负责封装IP地址。电脑现在的目的,是找DHCP服务器要IP地址,但他并不知道现在谁是DHCP服务器,不知道该发给谁,所以干脆一不做二不休,直接发给这个网络里的所有设备,所以目标IP是一个广播IP,`255.255.255.255`,同时接收方也需要知道是谁发给他的数据,所以还需要加上**源IP**,**但是电脑现在还没有IP**,于是会直接用`0.0.0.0`这个未指定的IP。 + +接着数据会继续向下 + +==来到网络接口层==,这一层会封装MAC地址,每个网卡都有唯一的MAC地址,也叫物理地址,源MAC是你电脑网卡的MAC地址,这里假设`CC:CC:CC:CC:CC:CC`,同样由于不知道数据该发给谁,所以目标MAC是一个全F的广播MAC地址,然后这个经过层层封装的数据包,会从电脑的网卡接口发出,顺着网线来到了交换机的1号接口,普通的家用交换机是一个,**只能解析网络接口层数据**的设备,也就是说他**只能看到MAC**地址,里面的IP和端口等信息,对他来说就是一堆无规则的数据,他看不懂也没必要看懂,交换机内部有一个MAC地址映射表,他会根据MAC地址对数据进行转发,至于你转发的什么内容,它并不关心。 + +交换机从LAN1收到数据后,会将LAN1对应的MAC地址保存到映射表中,然后查看目标MAC,发现是全F的广播MAC地址,于是交换机会将电脑的数据,给每一个连接的LAN口(Wifi也算)发送一份,当这台电脑收到数据包的时候,会根据网络模型一层一层的解封装,首先网络接口层会查看目标MAC地址是不是发给自己的,发现是全F,虽然不是自己的MAC地址DD,但这是一个广播MAC地址,所以会接受它,继续向上来到网络层,查看目标IP是全255,虽然不是自己的IP,但这是一个广播IP,广播就类似学校的广播,当广播里说全体注意的时候,**你肯定要听一下广播里他在讲啥**,所以电脑为了看里面的内容,也会接受这个数据包。 + +==来到传输层==,发现是通过UDP的方式发给67号端口,**由于这台电脑没有运行DHCP服务**,所以并没有监听67号端口,于是会将这个数据包丢弃。 + +同样的数据来到路由器,一般的家用路由器会提供很多服务,比如DHCP DNS DDNS Qos UPnP DMZ 端口转发 防火墙等等,接口层会接受这个目标MAC全F的广播,同样网络层会接受这个目标IP是全255的广播,向上来到传输层,发现目标端口是UDP的67,一般情况下路由器默认就开启了DHCP服务,而DHCP默认的监听端口就是UDP的67,于是这个数据包将会交给DHCP服务,DHCP服务收到数据后,将会从自己的IP地址池中,选择一个未被占用的IP地址。 + +假设为`192.168.1.3`,除了IP地址,还会包含子网掩码 网关 DNS服务器租约等信息。假设租约为12个小时,然后重新封装数据包,源端口是本机的DHCP服务67端口,目标端口是对方发过来的端口也就是68,并且通过UDP传输,网络层封装源IP地址为路由器自己的IP,也就是192.168.1.1,由于对方没有IP,所以目标IP还是全255的广播IP。 + +来到网络接口层,源MAC是路由器LAN口的MAC地址,路由器从刚才电脑发过来的数据包中,已经知道了电脑的MAC地址,所以目标MAC是电脑的MAC地址,数据来到交换机,刚才说过交换机只能解析MAC地址,当他看到目标MAC是CC的时候,会查看自己的MAC地址映射表,发现CC插在接口1上,于是会将这个数据包从接口1发送出去。电脑收到数据后会一层层的解封装。接口层发现目标MAC是自己。 + +于是接受该数据。网络层发现目标IP是广播IP,同样也接受了,传输层发现是发往UDP的68号端口,而DHCP客户端监听了该端口,于是数据将会由DHCP应用程序处理,DHCP会拿着这些信息,给电脑进行相关配置,于是我们的电脑就有了IP地址 网关DNS等信息了,并且在6个小时之后,也就是租约的1/2,会再次发起DHCP请求续约IP地址,**续约成功**的话,租期就会再次变成12个小时。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/image-20250116133729319.png)![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/image-20250116133842328.png) + +如果DHCP服务器没有回应的话。会在时间剩余1/4 1/8的时候,再尝试发送续约请求,如果续约成功,将会再次变成12个小时。如果失败了。说明路由器提供的DHCP==服务挂了==。等到租约到期之后。将会自动释放IP。然后重新发起DHCP获取IP的广播请求 + +但是由于这个局域网内,唯一的DHCP服务器挂了,所以电脑永远也得不到DHCP回应,当尝试多次都没有收到回复之后,DHCP客户端会给电脑,自动分配一个全球统一的网段,IP地址为169.254.X.X,确保和局域网的其他设备,还能正常通信,所以当你发现电脑获取到了169.254开头的IP,说明你家里的局域网中,没有提供DHCP服务的设备,建议检查网络。 + +除了一台都没有的情况,还有可能配置不当,导致整个局域网中,存在多台DHCP服务器的情况,这也会出现网络问题,这里存在**DHCP攻击**。 + +如果电脑关机了,没有再次发送续约请求,租约到期后,路由器的DHCP服务就会释放掉这个IP,重新放回地址池,再分配给其他有需要的人,所以像是机场或者商场之类的公共场所,WIFI设置的DHCP租期都会比较短,一般十来分钟,确保你人走后,IP能够尽快的释放出来给别人用,防止地址池被占满,家庭网络的话可以设置的久一点,一般默认是720分钟,也就是12个小时,这就是DHCP的整个执行流程。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/image-20250116135453759.png) + +实际的DHCP要更复杂。 + +==所以简单一点流程就是==:广播(目标 IP 为 `255.255.255.255`,目标 MAC 为 `FF:FF:FF:FF:FF:FF`)。路由器收到请求后,从 IP 地址池中分配一个 IP(如 `192.168.1.3`)给电脑,并附带子网掩码、网关和 DNS 信息。DHCP 分配的 IP 有租期(通常为 12 小时),电脑会在租期过半时尝试续约。如果续约失败,IP 会被释放,电脑会重新发起 DHCP 请求。 + +------ + +### 3. **域名解析(DNS 协议)** + +当你在浏览器输入 `baidu.com` 时,浏览器需要将域名转换为 IP 地址。电脑向路由器的 DNS 服务发送 DNS 请求(目标端口为 UDP 53)。路由器作为 DNS 中继,将请求转发给运营商提供的上游 DNS 服务器。上游 DNS 服务器返回 `baidu.com` 的 IP 地址(如 `220.181.38.148`)。路由器将 IP 地址缓存一段时间,局域网内的其他设备再次访问 `baidu.com` 时,可以直接从缓存中获取 IP。 + +------ + +### 4. **地址解析协议(ARP 协议)** + +ARP协议就是根据IP地址查询Mac地址的协议 + +我是`192.168.1.3` + +谁是`192.168.1.1` + +这里贴一个YouTube地址,讲的非常好, + +[https://www.youtube.com/watch?v=P38FmPAq09E&t=183s](https://www.youtube.com/watch?v=P38FmPAq09E&t=183s) + +------ + +### 5. **访问百度服务器(HTTP 请求)** + +拿到百度服务器的 IP 地址后,浏览器向这个IP发起一条 HTTP 请求(目标端口为 TCP 80)。电脑发现目标 IP 不在同一网段(通过子网掩码判断),于是将数据包发送给默认网关(路由器)。路由器通过 NAT(`Network Address Translation`网络地址转换)将内网 IP(`192.168.1.3`)转换为路由器WAN口公网 IP(`2.2.2.2`),并随机选择一个端口,替换掉源端口,并记录端口映射,此时数据就可以在公网上路由了。 + +接着封装MAC地址,源MAC是路由器WAN的MAC地址,目标MAC是吓一跳某个路由设备的MAC,然后数据从WAN口发送到了互联网,经过十几个路由设备转发,最终到达百度服务器。百度服务器处理请求后,将网页数据返回给路由器,路由器通过 NAT 将数据转发给电脑。 + +------ + +### 6. **关键技术与协议** + +- **DHCP**:动态分配 IP 地址,简化网络配置。 +- **DNS**:将域名转换为 IP 地址,方便用户访问网站。 +- **NAT**:将内网 IP 转换为公网 IP,实现多设备共享公网 IP。 +- **ARP**:通过广播获取目标设备的 MAC 地址。 +- **TCP/IP**:分层网络模型,确保数据可靠传输。 + +------ + +### 7. **总结** + +从输入 `baidu.com` 到页面加载完成,背后涉及了 DHCP、DNS、ARP、NAT、TCP/IP 等多种网络协议和技术的协同工作。虽然过程复杂,但现代网络设备和协议的高效性使得这一切在不到1秒的时间内完成。 \ No newline at end of file diff --git "a/src/fundamental/network/8.DHCP\345\215\217\350\256\256.md" "b/src/fundamental/network/8.DHCP\345\215\217\350\256\256.md" new file mode 100644 index 0000000..89a68d0 --- /dev/null +++ "b/src/fundamental/network/8.DHCP\345\215\217\350\256\256.md" @@ -0,0 +1,87 @@ +--- +order: 8 +author: +title: "DHCP协议?" +category: + - TCP + - UDP + - 计网 + +--- + + + +每一个网络设备,都有一个此网络中的独一无二的IP地址,也用来作为网络通信中的唯一标识,那: + +- 每个设备的ip地址是如何得到的呢? + +- 又是如何保证不冲突的呢? + +那就引出了下面的,**DHCP(动态主机配置协议)** + +:::info + +静态 IP是手动分配给设备的固定 IP 地址,不会自动更改,适合需要长期稳定连接的设备,如服务器、打印机等,但是需要手动输入 IP 地址、子网掩码、网关和 DNS 服务器。需要手动输入 IP 地址、子网掩码、网关和 DNS 服务器。 + +比如,对于拥有一千台服务器的集群,网络管理员需要根据设备编号,对每台设备设置固定的IP。 + +还有,你要静态设置的话,你要提前知道你家里的局域网的网段是哪个,比如我家的路由器地址是,![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/image-20250116135646690.png),那么你的设别就要在`192.168.1.2`~`192.168.1.254`之间。 + +网关和DNS默认设置为路由器的IP。 + +::: + +DHCP 是一种自动化的 IP 地址分配协议,设备(如电脑、手机、路由器等)在连接到网络时,它会向 DHCP 服务器发送一个请求,DHCP 服务器会从可用的 IP 地址池中选择一个未被使用的地址,分配给设备。这个 IP 地址通常有一个租期,租期到期后设备可能会获得不同的 IP 地址。 + +**优点**: + +- 自动化分配 IP 地址,节省手动配置的时间和精力。 +- 可以动态管理网络中的设备,不需要手动干预。 +- 避免了 IP 地址冲突,DHCP 服务器会确保每个设备得到唯一的 IP 地址。 + +**缺点**: + +- 因为 IP 地址是临时分配的,设备的 IP 地址可能会发生变化,适用于不需要固定 IP 的设备。 +- 一些应用需要固定 IP 地址来进行通信(如服务器、打印机等)。 + +**巴拉巴拉:** + +当你的电脑通过网线连接到路由器,当电脑开机进入操作系统后,此时其还没有IP地址,操作系统会通过UDP协议,此时其还没有IP地址,操作系统会使用udp协议通过68端口向67端口广播一包DHCP discover数据包,用来寻找DHCP服务器。 + +由于这是一个广播数据包,所以网络中的所有设备都会收到这一条数据。但是只有DHCP服务器才会做出响应,在家庭网络中路由器就是DHCP服务器的角色。 + +他收到的DHCP discover数据包后,知道网络中有设备需要分配IP地址。所以他需要在自己的IP地址池中拿到一个空闲IP,比如192.168.1.10,并决定把这个IP地址分配给路由器。 + +路由器会把此IP封装成一包DHCP offer包,回复给我的PC。PC收到后要决定用不用这个IP地址。 + +为什么会有这一步?是因为假设网络中有多个DHCP服务器,他们有可能会同时收到discover包,各自分配IP地址后回复DHCP offer包。此时PC会收到多个他要决定用哪一个IP地址,一般情况下都是用收到的第一个IP地址。 + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/image-20250116121017109.png) + +决定好后,PC会向网络中广播自己的决定,通知路由器接受了其分配的IP地址。这一包称为DHCP request包。 + +:::danger +其实上图并不准确,如果电脑用网线连接,电脑广播的时候,会先向LAN口发送,然后由交换机(路由器)中的MAC地址映射表负责转发, + +转发的对象也不只是其他DHCP服务器,普通设备也会被发送,但是由于MAC地址的不同,普通设备就会被pass掉。 + +::: + + + + + +![](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/image-20250116120935207.png) + +路由器收到request包后会回复给PC DHCP ack包,表示已经接受了PC的选择,可以使用此IP地址,此时pc拥有了自己的IP地址。 + +以上四步就是DHCP获取IP地址的完整流程。不过前两部并不是必须的,当PC重启后,PC无需重新获取IP地址。只需要再次确认就可以了。 + +![重启后,PC无需重新获取IP地址](https://qtp-1324720525.cos.ap-shanghai.myqcloud.com/blog/image-20250116121218769.png) + +就是从第三步开始发送DHCP request的包,直接请求使用此IP。DHCP服务器需要检查此IP是否可用,若可以使用则直接回复ack包确认可以继续使用此IP地址,若不可用比如此IP已被其他设备占用,则回复DHCP nack包拒绝申请,此时PC需要从DHCP discover开始再来一次完整的申请流程。 + +家庭网络中的包括通过网线连接路由器的电脑,以及通过WiFi连接的手机,电视,游戏机等。都是通过以上的步骤获取IP地址的,获取IP地址后,他们就可以在网络中互相通信了。 + + + diff --git a/src/opensource/Clash.md b/src/opensource/Clash.md new file mode 100644 index 0000000..b8ec541 --- /dev/null +++ b/src/opensource/Clash.md @@ -0,0 +1,9 @@ +--- +order: 4 +author: +title: "Clash技术架构及内核" +category: + - Clash + - 内核 +--- + diff --git a/src/opensource/tool.md b/src/opensource/tool.md index 5e87e74..a948e49 100644 --- a/src/opensource/tool.md +++ b/src/opensource/tool.md @@ -14,4 +14,6 @@ category: electron-egg -ip代理池 \ No newline at end of file +ip代理池 + +双币信用卡,动物之森,Half Life Alyx \ No newline at end of file diff --git a/src/projectessay/scaffold/5.Md document Common containers and emoticonsr.md b/src/projectessay/scaffold/5.Md document Common containers and emoticonsr.md index 8b19d8a..2f34021 100644 --- a/src/projectessay/scaffold/5.Md document Common containers and emoticonsr.md +++ b/src/projectessay/scaffold/5.Md document Common containers and emoticonsr.md @@ -21,8 +21,6 @@ category: ::: ``` - - ### 2. 提示 :::tip @@ -130,6 +128,14 @@ category: - [ ] 发布博客文章 - [ ] 学习 React +``` +- [x] 完成 Markdown 学习 +- [ ] 发布博客文章 +- [ ] 学习 React +``` + + + ### 10.内嵌视频