MAC 和 IP 地址
当下计算机发展火热,每年不计其数的学生投奔这个行业,匆匆忙忙学一门编程语言,急急忙忙找一份工作。平时对于工作内容滚瓜烂熟,但是总感觉自己基础并不牢固,想要夯实基础,却又无从着手。平时碎片时间学到了很多,但知识点总是串不起来。这非常正常,计算机这几十年的迅猛发展,带来了巨量的知识内容,甚至每天都在更新全新的技术。滚滚车轮下,没人可以了解一切,人们只是在不断追逐。万幸的是,计算机并不同于自然科学,自然科学通常究其根源是无解的,或者说当下无解。但计算机不同,它是人类一手发展起来的,它是有明确的原理和根源的,只要你将探究的目的限制于计算机体系而不是其物理原理,那么一切都是有解的。整个计算机体系基于相同的源头,已经形成了许多重要的支柱,所有的一切新的技术都在支柱之上伸展。大家面对汹涌的潮流,更应该做的是抓住支柱,从支柱出发学习,蔓延到感兴趣的一切目的地。
计算机网络就是其中一大支柱,这是一个及其繁荣的体系,涉及名词繁多。如果每次学习总是只看到一片树叶,而不知其全貌未免太过可惜。其实说来复杂,但计算机网络也就几十年的历史,不如我们跟随发展的脉络,分析发展中遇到了什么问题,使用了什么技术解决问题,导致了什么结果。顺着这样的思路,我们能看到整个计算机网络体系从发芽到开枝散叶,直到开出繁花。
我们联合
让我们回到计算机网络的蛮荒时期,此时,我们面临的情况很简单:大学实验室里有几台新奇的玩意叫计算机,有同学希望能否将其中一台计算机的计算结果拿到另一台计算机中使用。要实现其实并不困难,如果是打孔计算机,那么只需要将计算结果打孔纸条,然后将纸条拿到另一台计算机读取即可。可是有同学嫌麻烦,他认为这样效率太低,还需要自己动手,于是他有了自己的想法:计算机计算结果是电信号
另一台计算机使用的也是电信号
如果能直接连接两台计算机的电信号,那么就不需要使用纸条作为中间介质
使用电缆连接两台计算机的某个引脚
编写计算机程序,使源计算机将计算结果输出到指定引脚
编写计算机程序,使目的计算机读取指定引脚的输入
将上述控制电信号的硬件和软件封装起来,并给这个设备取个名字,就叫控制器
将控制器装到实验室的每台计算机上,每个计算机都可以将计算结果传给其他计算机,把这个行为就做通信,整个体系我们称为网络
最后随着时间发展,控制器逐渐有了更明确的名称:网络接口控制器,简称网卡
看!网络雏形出现了,后续网络体系发展的及其庞大,人们为了方便,将计算机分层,有7层的,也有5层的,不管怎样,上述体系一般都会分配到计算机网络体系的最底层,一般称为网络接口层。你的名字
相信聪明的小伙伴们看出来了,上述描述中两台计算机直接通过电缆通信是很合理的,计算机直接将计算结果通过电信号传给另一台计算机。但是当实验室中所有的计算机都接入了电缆,电缆形成了网状结构后,计算结果就传给所有其他计算机了,但是我不想影响到其他同学们的计算机,只想把我的计算结果传递给最好的同学小明同学,那应该怎么办。没错,不知不觉中,我们已经了解到了“广播”的概念,广播这个概念出现是非常顺理成章的,网络通讯控制反而才是网络使用中出现的新问题。为了解决这个问题,人们很自然的给每个计算机取名字/编号。这台计算机是A,那台计算机是小明同学的,那台叫他 beta 好了,还有那台又破又慢,就叫“垃圾”好了…不管怎样,计算机们第一次有了身份标识,用于在计算机网络中表明自身。此时,beta 的计算结果打算传给小明同学,那么它只需要在结果前面附上自己的代号以及目标的代号:beta|小明同学,然后电信号通过电缆广播出去,所有计算机都会收到消息,并核对是不是发给自己的,如果不是则丢弃,只有小明同学才需要去获取这条消息。
很多同学已经恍然大悟,这不就是MAC地址吗?是的,将计算机的代号规范化后固定为48位(6字节),我们就得到了 MAC(Media Access Control) 地址,在实际应用中 MAC 地址是在网卡生产时写入到 ROM 里的。跟beta在计算结果前面添加“beta|小明同学”类似,在计算机网络中,每次通信都需要在消息前面添加 MAC 头部,格式为:
接收方 MAC 地址(48位),发送方 MAC 地址(48位),协议类型(16位)。
其中协议类型(16位)是用来告诉通信目标我这次传输的是什么类型的消息。用于标识上层协议的类型。
常见的协议类型数值包括:
0x0800:表示上层协议是 IPv4。
0x86DD:表示上层协议是 IPv6。
0x0806:表示上层协议是 ARP(地址解析协议)。
0x0808:表示上层协议是帧中继(Frame Relay)。
0x8100:表示上层协议是 VLAN 标记(Virtual LAN Tagging)
- 既生瑜何生亮
随着实验室计算机的增加,每次像发送消息给小明同学都要广播给所有计算机显得越来越愚蠢了。于是,你灵光一闪——集权,没错,你打算增加一个控制设备,所有的计算机都接入这台设备,它就是邮局,每台计算机发送消息就去邮局投递信件,说清楚你要将信件寄给小明同学,这样控制设备就直接将信件交给目标,不再打扰其他同学们干活了。这个设备不如就叫交换机吧。
但这样一来,交换机上肯定得清楚地知道实验室里面都有多少台计算机,每台计算机叫什么,不然它也没法将信件交给准备的目标。因此交换机上维护了一张清单,里面登记了所有计算机的 MAC 地址以及其对应的端口,每次收到信件,交换机就查询这张清单上对应 MAC 地址的端口,将信件发过去,我们把这张清单叫做 MAC 地址表,或者路由表。
问题再次得到了解决,直到隔壁某一天,你需要和隔壁学校合作,将你计算机的计算结果传给隔壁学校的计算机。
此时,方法可以很粗暴,直接拉一条电缆将对方计算机接入你实验室所在的网络,同时也在 MAC 地址表上添加记录。不久,小明同学也参加了项目,需要和对方另一台计算机通信,你发现不对劲了,不能每多一位同学就拉一条电缆,其他不说,就显得很蠢。
庆幸的是隔壁学校的同学们也很聪明,也使用了交换机控制通信。那么你们只需要将双方的交换机连接在一起,相互同步自身的 MAC 地址表,发现目标地址是隔壁学校的,就将信件交给对方的交换机,让对方代为转交。
问题得到了解决,很快,两个学校的合作事迹传遍全城,所有学校都急忙加入了进来,数量庞大的计算机都接入了网络,MAC 地址表越来越臃肿了。并且,很多学校并不愿意公开自己内部的计算机信息,地址表的信息开始失真,MAC 地址表的维护变成了新的问题。
基于上述问题,一个天才般的方案诞生了。中心思想是分治,每个学校自己管理内部的计算机,学校之间通信则使用学校名+计算机名,其中计算机名由学校自己分配,这个方案就是大名鼎鼎的IP(Internet Protocol)协议。
其中学校名+计算机名推广为网络号+主机号,网络号负责标识 IP 地址属于哪个学校,主机号负责标识同一个学校下的计算机。 总长度定为了32位,分成了四段(比如192.168.1.1)。同时为了使得网络号长度可变,添加了子网掩码。例如子网掩码255.255.255.0,转为二进制是「11111111-11111111-11111111-00000000」,也就是说网络号的长度为24,主机号的长度为8,一个完整的 IP 地址表示为 192.168.1.1/24,其中/24表示子网掩码255.255.255.0。
只要将 IP 地址和子网掩码按位与运算就能得到网络号,将 IP 地址和子网掩码取反后进行按位与运算就能得到主机号。
回到学校问题上,不同学校使用不同的网络号,内部自由分配主机号。通信时,交换机发现目标 IP 地址是相同网络号的,就可以使用维护的 MAC 地址表,或者使用新的 IP 地址表将信件传递给目标。如果发现目标 IP 网络号对不上,那么就转发给网络号对应的另一个学校的交换机即可。对了,此时交换机需要提供寻址和路由功能,此时应该将其称为路由器会更加合适。