记录一下自己所理解的计网相关概念
最近上计网课,见识到了很多平日网上冲浪时经常会听到的一些计算机网络相关的名词,像 \(IP、DNS、\)网关、子网掩码之类的,一开始学的时候还挺不以为然的,心想这些我都知道,但仔细思考一波,却发现自己其实对这些术语并不是十分了解,只有一些模糊的概念,知其然而不知其所以然。于是就到处查阅了一些资料,学习了一波,现专门写一篇博客,用来整理一下最近所学的这些计算机网络相关的概念,以便于日后的复习。
PS:以下内容纯属本人个人理解,且基本只涉及到概念方面,底层实现和各类细节完全不太了解,可能会有很多错误,若路过的某位大佬发现哪里说的不对,欢迎指正,万分感谢!
为了方便描述,我们在日常生活中所常用的手机、计算机、游戏机等联网主机在下文中统称为主机,且在计算 \(\rm IP\) 地址数量时不会刻意减去某些特殊的、不允许大众使用的地址。
网络协议(networking protocol)
首先,学计算机网络,一定会看到各种网络协议,什么 \(\rm IP\) 协议啊、\(\rm TCP\) 协议啊、\(\rm UDP\) 协议啊之类的。那么到底什么是网络协议(以下简称协议)?
我们知道,主机所读取到的数据本质上都是用物理层面上的各种基本物理信号来表示的一连串的 \(01\) 字符串。
在通信时,我们首先要制定一套通用的规则,使得传输过去的基本物理信号能被正确地翻译成一串 \(01\) 字符串,这套翻译的规则即是一个协议;
有了数据的 \(01\) 字符串,我们还得根据另一套通用的规则把这个数据打包起来,贴上寄件人和收件人(不然你用英语写收件人,他用日语写寄件人,快递员是个中国人,完全看不懂,怎么办?都给????用中文!),这套打包的规则也是一个协议;
传输数据的时候,要从某一个驿站送到另一个驿站,在两个驿站之间有多条路应该选择哪一条路,又有一套通用的规则规定了这些行为,这套运输的规则还是一个协议……
一言以蔽之,协议就是主机在通信时需要遵守的一套人为规定、并由代码实现的规则。有了这样一套大伙能接受并遵守的标准规则,我们才可以在各类硬件不同、使用的软件也不同的主机之间通信了。举个栗子:
为了让一个不会中文的美国人和一个不会英语的中国人能够讨论“你最喜欢看的动漫是什么”这一话题,咱们制定一套国际通用语,美国人自觉把自己想说的英语翻译成国际通用语,说给中国人听,中国人再把国际通用语翻译回中文并加以理解,之后回话时进行相同的操作,这里的“把英语翻译成国际通用语”和“把国际通用语翻译回中文”所遵循的一套规则就是协议了。
别问我为啥不让美国人学中文或者让中国人学英语
IP地址(Internet Protocol Address)
在众多协议中,\(\rm IP(Internet\ Protocol)\) 协议(以下简称 \(\rm IP\))无疑是出现频率最高的,目前我们主要使用的是 \(\rm IPv4(Internet\ Protocol\ version\ 4)\),因此本文只介绍 \(\rm IPv4\)才不是因为我根本不了解 IPv6,它采用 \(\rm 32bit\) 的二进制字符串来表示 \(\rm IP\) 地址,那么现在问题来了:挖掘机学校哪家强 \(\rm IP\) 地址是啥?
众所周知,主机在通信的时候,都是通过各种方法,把相关的数据传输来传输去,从而实现一系列操作的,比如你用电脑下载某款软件时,该款软件的相关代码会被打包成一个又一个的数据包,然后通过网络,从软件代码所在的服务器传输到你的电脑上,此时的数据就像一个快递,要从某个地方,送往另一个地方,既有寄件人,也有收件人,而这所谓的“收件人”的身份证(即能够在网络上唯一标识这个收件人是谁的标志),就是一台主机在网络上的 \(\rm IP\) 地址,有了这个,在数据传输的过程中,各个主机就能知道它们到底该把数据往哪里送;并且,为了保证数据能够准确无误地送达,每台主机的 \(\rm IP\) 地址都是唯一的,不然的话,如果某个快递要送到身份证号为 \(XXX\) 的人身上,但世界上存在两个身份证号为 \(XXX\) 的人,那快递小哥送快递的时候到底该送给谁呢?笑死,根本送不好。
用官方一点的话来讲:\(\rm IP\) 地址是 \(\rm IP\) 提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异,同时提供标识主机和网络寻址的功能。
MAC地址(Media Access Control Address)
由于 \(\rm TCP/IP\) 协议中的数据链路层的存在,我们在网络上传输数据时,仅靠上面提到的 \(\rm IP\) 地址作为逻辑地址来定位某台主机其实是不够的,还需要一个物理地址来唯一地标识它,即 \(\rm MAC\) 地址。两个地址一起,才能在唯一确认一台主机的同时与这台主机进行通信。一台主机想要能够上网,肯定是得装个网卡的,而每个网卡在厂里制作的时候都会写入一个 \(48\rm bit\)、通常用 \(12\) 个 \(16\) 进制数表示的字符串,作为这张网卡在网络上的身份证号,这便是该网卡的 \(\rm MAC\) 地址,日后当这个 \(MAC\) 地址为 \(XXX\) 的网卡装在某台主机上时,我们就可以说这台主机的 \(\rm MAC\) 地址是 \(XXX\)(当然一台主机可以装多个网卡,到时候就看你用哪个网卡联网)。
子网掩码
首先我们得知道,\(\mathbf {IP}\) 地址 = 网络地址 + 主机地址(又称网络号和主机号),网络号相等(即处在同一个网络下)的两台主机可以直接进行数据通信,否则就需要通过路由器转发数据,会多耗费一些时间和资源,为了方便记忆,常用 \(4\) 个 \(\in[0,255]\) 的十进制数和三个分割点表示一个 \(\rm IP\) 地址,例如 \(1.14.51.4\)。在早期,\(\rm IP\) 地址根据网络号的字节长度划分为 \(5\) 类,如下表:
A类IPv4地址 | B类IPv4地址 | C类IPv4地址 | D类IPv4地址 | E类IPv4地址 | |
网络号字节数 | 1 | 2 | 3 | --- | --- |
网络标志位 | 0 | 10 | 110 | 1110 | 11110 |
IP地址范围 | 0.0.0.0~127.255.255.255 | 128.0.0.0~191.255.255.255 | 192.0.0.0~223.255.255.255 | 224.0.0.0~239.255.255.255 | 240.0.0.0~255.255.255.255 |
可用IP地址范围 | 1.0.0.1~127.255.255.254 | 128.0.0.1~191.255.255.254 | 192.0.0.1~223.255.255.254 | ||
是否可以分配给主机使用 | 是 | 是 | 是 | 否 | 否 |
网络数量(个) | 126 (27-2) | 16384 (214) | 2097152 (221) | --- | --- |
每个网络中可容纳主机数(个) | 16777214 (224-2) | 65534 (216-2) | 254 (28-2) | --- | --- |
适用范围 | 大量主机的大型网络 | 中等规模主机数的网络 | 小型局域网 | 留给Internet体系结构委员会(IAB)使用组播地址 | 保留,仅作为搜索、Internet的实验和开发用 |
备注 | 0.0.0.0为特殊地址,表示本网主机 | 255.255.255.255为特殊地址,用于定向广播 |
一些特殊的 $\mathbf {IP}$ 地址也贴一下(不同 RFC 版本可能会略有不同)
网络号 | 主机号 | 是否可以作为源地址 | 是否可以作为目的地址 | 备注/描述 |
全为0 | 全为0 | 允许 | 禁止 | 表示本网主机 |
全为0 | Host ID | 允许 | 禁止 | 表示特定主机 |
全为1 | 全为1 | 禁止 | 允许 | 定向广播地址 |
127 | 任意合法的值 | 允许 | 允许 | 迂回地址,用于本地测试 |
Network ID | 全为1 | 禁止 | 允许 | 直接广播地址 |
同时,由一个叫做 \(\rm ICANN\) 的非盈利组织来管理这 \(5\) 类网络号,该组织会把某些个网络号委托给各种区域性的权威机构,然后这些权威机构又将该网络号所属的 \(\rm IP\) 地址分配给 \(\rm ISP\) 和某些有需求的公司。
显然,这种分类机制很容易造成极大的资源浪费,举个栗子:假设我要给某所大学分配一个网络号,这所大学有 \(9e5\) 台主机需要联网,直接分配给它一个 \(A\) 类网络号,显然会造成大量浪费;分配一个 \(B\) 类网络号,显然不够;分配两个 \(B\) 类网络号,也会造成部分浪费;分配多个 \(C\) 类网络号,又得多搞几个路由器,还是浪费了人力物力财力。这也使得地址空间无法得到最大限度的利用,这在互联网发展早期还好,大伙心想着浪费了就浪费了吧,但随着联网的主机爆发性增长,地址短缺的问题也逐渐暴露出来了。毕竟就算加上那些特殊的、一般情况下不可使用的 \(\rm IP\) 地址,最多也只能给 \(2^{32}\) 台主机一机发一个合法身份证,再多的话就没得发了,而全世界人口 \(70\) 多亿,虽然不敢说所有人都会上网,但一般一个会上网的人不会只有一台主机,因此实际上 \(\rm IP\) 地址的数量是远远不够的,这种地址资源紧缺的情况下你还铺张浪费,就有点憨批了。于是就有了子网掩码,用来把 \(\rm IP\) 地址网络号的分类进一步地细化,减少资源的浪费。
子网子网,顾名思义,就是在早期的 \(5\) 大类网络中重新划分出来的小网络,而子网掩码就是用来告诉主机到底该怎么划分小网络的,它也是一个 \(\rm 32bit\) 的数字串,前面连续 \(x\) 个 \(1\),后面连续 \(y\) 个 \(0\),\(x+y=32\)。给你一个 \(\rm IP\) 地址 ,再给你一个子网掩码,假设子网掩码前面有 \(x\) 个连续的 \(1\),\(\rm IP\) 地址的真 \(\mathbf\cdot\) 网络号就是就是它的前 \(x\) 位(二进制下哈),剩下的位全填 \(0\) 就行(或者说网络号为 \(\rm IP\) 地址与子网掩码做与运算的结果)。举个栗子:
某台主机的 \(\rm IP\) 地址是 \(1.14.51.4\),子网掩码是 \(255.255.252.0\)。
先把它们都转化为二进制,分别是 \(\mathbf {0000\ 0000\ .\ 0000\ 1110\ .\ 0011\ 0011\ .\ 0000\ 0100 }\) 和 \(\mathbf {1111\ 1111\ .\ 1111 \ 1111\ .\ 1111\ 1100\ .\ 0000\ 0000}\)。
发现子网掩码前面有 \(22\) 个 \(1\),所以取 \(\rm IP\) 地址的前 \(22\) 位作为它真正的网络号,剩下的全填 \(0\),即 \(\mathbf {0000\ 0000\ .\ 0000\ 1110\ .\ 0011\ 00|00\ .\ 0000\ 0000}\),主机号则由剩下的 \(10\) 位决定,每一位都可以任取 \(0\ or\ 1\),该子网可以让 \(2^{10}\) 台主机联网,也就是说,子网掩码的存在让 \(\rm IP\) 地址网络号的划分更细了,减少了地址的浪费,同时也使得主机可以分配相同的 \(\rm IP\) 地址了(比如 \(\rm IP\) 地址同样是 \(11.4.51.4\) 的两台主机,只要子网掩码不同,就是完全 \(ok\) 的),极大地减缓了 \(\rm IP\) 地址枯竭的速度但还是远远不够。
网关
想象这么一个场景,学校两个机房里的电脑分别连成了一个局域网 \(A\) 和 局域网 \(B\),网络号分别是 \(11.45.14.0\) 和 \(191.198.10.0\),上面说过,不同网络号的主机不在同一网络下,不能直接进行通信,此时就需要使用路由器把它俩连起来——\(A\) 中主机的数据想要发送给 \(B\) 中主机,就必须先发给路由器 \(C\),然后再由路由器 \(C\) 转发给路由器 \(D\),最后再由路由器 \(D\) 转发给 \(B\) 中主机。此时路由器显然也可以作为一台主机,于是我们给路由器分配一个 \(\rm IP\) 地址,使得 \(A\) 中主机想要给 \(B\) 中主机发送数据时,能够知道它应该把数据交给 \(C\),\(C\) 会帮它转发给 \(B\)。
那到底啥是网关呢?其实上面提到的路由器的的 \(\rm IP\) 地址就是一个网关,即网关实质上是一个网络通向其他网络的 \(\rm IP\) 地址,早期的 \(\rm RFC\) 中也把路由器称为网关,后来才逐渐使用了路由器这一说法。
如图所示,网关其实也是个 IP 地址
DNS(Domain Name System)
即域名系统,域名是对一个 \(\rm IP\) 地址的别名,比如 \(www.baidu.com\) 就是一个域名,它所映射的 \(\rm IP\) 地址是 :\(36.152.44.98\)。因为 \(\rm IP\) 地址相对来说不是那么好记,所以把它转化为一个好记的形式,可以理解为 #define ll long long
,因为 long long
打起来比较麻烦,所以我们用 ll
来代替它,此时 ll
就是域名,long long
则是 \(\rm IP\) 地址。当我们想访问某个网站时,直接输 \(\rm IP\) 地址和输这个地址对应的域名是等价的,而域名系统就是将大量登记好的域名及其对应的 \(\rm IP\) 地址制成一张表,便于我们能够更加方便的访问互联网。\(\rm DNS\) 服务器则是在我们想访问某个网站并输入它的域名时,帮我们从表中取出相对应的 \(\rm IP\) 地址的服务器,所以当你的 \(\rm DNS\) 服务器出问题时,你仍然可以登录 \(QQ\),但不能浏览网页(因为浏览网页时一般都会使用域名,而 \(QQ\) 是一款软件,跟它相关的数据通信不需要使用域名)。
而 \(hosts\) 则是一个在你本机上的小型 \(\rm DNS\) 服务器,\(Windows\) 系统下的默认路径一般是 \(C:\backslash Windows\backslash System32\backslash driver\backslash etc\),当你访问某个域名时,你的主机会先在 \(hosts\) 文件里找对应的 \(\rm IP\) 地址,找不到时,则会转去使用你所设置的 \(\rm DNS\) 服务器来找,还找不到,就会访问失败。
内网和外网
内网又称局域网(\(Local\ Area\ Network,\ LAN\))、私网,可以理解为在某一个小范围区域内、利用多台主机和若干个路由器互联而成搭建的小型网络,比如一个学校的校园网、公司的网络、家里的网络等;外网又称广域网(\(Wide\ Area\ Network,\ WAN\))、公网,只要范围够大,由许多个内网互联而成,就可以说这是一个广域网。
这俩概念其实都是相对来说的,没什么规范的定义,你可以说 \(Internet\) 就是一个广域网;也可以说一个覆盖某市的大型网络够大,是广域网;也可以说覆盖某省的大型网络其实是 \(Internet\) 的子网,即一个局域网。一个看上去很大的网络实际上可能还是某个更大的子网,但这个网络又足够大,此时既可以叫它广域网,也可以叫它局域网,真正有区别的,还是看你从哪个角度去看它,如果你是从它的某个子网来看,你可以说这个子网属于他这个广域网;如果你是从它上面的那个更大的网络来看,那你也可以说它是这个更大网络中的某个局域网,得根据现实中的网络结构来具体情况具体分析。
要特别注意的是,我们经常说的 \(\rm IP\) 地址其实是公网 \(\rm IP\) 地址,它在全世界范围具有唯一性,快枯竭的 \(\rm IP\) 地址指的也是它;而我们日常生活中分配到的 \(\rm IP\) 地址通常都是私网 \(\rm IP\) 地址,它只在它所处的局域网中有效且只在该网络内部具有唯一性。因此,我们可以只分配少量的公网 \(\rm IP\) 地址,同时利用某种技术在这个公网下搭建许多私网,然后不同的私网之间可以使用相同的 \(\rm IP\) 地址而互不影响,这样就可以让许多主机都连上网而不用担心 \(\rm IP\) 地址不够分,正是靠着这项技术,才使得本早应该枯竭的 \(\rm IPv4\) 地址苟了这么多年至于到底是哪项技术这么牛逼我就不知道了。这么说可能有点抽象,举个简单的栗子:
世界上只有一所枝江大学,但很多所大学都有逸夫楼,当你要把快递送到枝江大学的逸夫楼时,你只需要把它送到枝江大学,然后枝江大学的驿站自己会想办法把这个快递送到学校里的逸夫楼,这里的枝江大学就是公网 \(\rm IP\) 地址,逸夫楼就是私网 \(\rm IP\) 地址。
通过这个例子我们其实也可以看出,某种以上,拥有公网 \(\rm IP\) 地址的网络就是外网,只有私网 \(\rm IP\) 地址的网络就是内网,至于怎么判断自家主机到底是内网还是外网,这里就不多做介绍了,有兴趣的同学可以自己百度(好像还是跟网络号有关)。
对了,补充一下,由于现在公网 \(\rm IP\) 地址资源紧张,我们办宽带业务时一般都会给我们分配私网 \(\rm IP\) 地址,如果想要公网 \(\rm IP\) 地址的话,得自己去申请,不过一般都挺难申请到的,当然了,公网 \(\rm IP\) 肯定是比私网的要好一些:首先不需要经过 \(N\) 多网关的转发,就能直接连上 \(Internet\),网速一般会比较快;其次也没有墙了,可以随意遨游墙外的世界(一般墙都设在网关上)。