关于网络的简单介绍...
写在前面
这篇简易教程的内容只涉及计算机网络的基础入门类知识。
你可以在这里找到关于网络编程,你需要了解的基础内容:Lecture.21至Lecture.26
如果你有兴趣知道这些分立的电子设备是如何把这个世界连在一起的,那么你可以接着往下看看。在这里,我们只讨论最基础的有线网络。接下来就这个话题,从我有话可说的几个地方简单聊聊
一切的基础
我们知道,最简单通信方式是纸杯电话。两个纸杯,一根紧绷的线,就能够把我们说的话从一个杯子传递到另一个杯子。在这里,我们说的话是信息,把纸杯看做两个端点,那么那根紧绷的线就是信息的载体。这个模型可以用来理解现在所有的信息传递方式,它的过程大概是这样
信源发送信息,在纸杯的一端,甲开始对着纸杯说话
信息被编码成能够通过载体传递的形式:甲的声音产生振动,通过共振让线(载体)振动
载体中的信息被通信的另一端点解码成另一端点能够理解的形式:乙的纸杯随着振动,传来甲说的话
这样就完成了一次信息传递。
但在通信过程中,通信距离也是我们必须考虑的因素。如果你的通信距离只有从玉子的窗户到饼藏的窗户那么短,纸杯电话能够轻松应对;但在其他更多时候,它就不是那么实用了。
再来看另一个小游戏:7个人排成一列,每个人根据前一个人比划的动作猜测一个词语,再根据他所猜想的内容向下一个人比划。在这里,信息的载体自然就成了人们所做的动作。我们发现,最后一个人看完倒数第二个人做出的动作后,所做出的猜测总是和原来的词语大相径庭。这样的结果并不意外:每个端点都是独立的端点,而他们都有自己独特的理解外来信息的方式和向别人传递信息的方式;简单来说,他们对同一个信息的编码和解码的方式都不相同(虽然我们并不知道他到底猜没猜对“同一个信息”!)
这时,通信可靠性的重要之处就凸显出来。如果将军在外打了胜仗,当然希望回国后能够看到举国欢庆的场面,而不是看到大家错误地以为大难临头,人去楼空的场面。
为了实现让所有人步调一致,历史上所有的人类都做出了不同程度的努力。中国古代的军事设施“烽火”会在白天燃烧掺有粪便的柴草,释放浓烟,以为“燧”,夜晚则会燃烧加有硫磺和硝石的干柴,使火光通明,以便传递紧急信息,以为“烽”;在比电报更早的时候,一名英国人曾提出用26条电线代表26个字母,发送对应的字母则将对应的电线带上静电;而接收方则在各电线上接上小纸条,当纸条因静电而升起时,便能誊录文本;灯号、旗语,人们不断改进传递信息的方式,在今天,我们使用“协议”来做到古人做不到的事。
组网与协议
集线器
像纸杯电话一样,把两台计算机用线连接起来,就能够实现电脑之间的通信。如果电脑增多,只需要添加一些网线。这样的传输结构叫做以太网,是构成局域网的最简单方式。然而当电脑太多的时候,这个由线路构成的网络将非常复杂。这时人们想到,
这时,如果我们把所有线都连到一台设备上,让这个设备将信息转发到每个端口。这就是集线器。计算机通过向集线器发送信息,由集线器转发。但这样做的坏处是,我们所发送的每一条消息都会被群发到所有接入集线器的设备,这样的行为是对网络资源极大的浪费,更重要的是,信息的私密性安全也无法得到保证。
交换机
这时,如果我们能为每台计算机起一个名字就好了。当我们想要传送私密消息时,便可以像信件一样写上寄件人和收件人。这就是Mac地址,,它看起来像这样:
xx:xx:xx:xx:xx:xx
当数据包被发出时,发送者和接受者的Mac地址会像信件地址一样附加在数据包的包头。
mac地址共48位,用冒号分成6字节。它的含义是这样解读的:
第一个字节的最低1-2位:最低有效比特(位)标识单播地址(0)/多播地址(1),从最低有效比特开始的第二位标识广域地址(0)/区域地址(1);
从第3位开始到第24位:由IEEE分配给各网卡制造商,各不重复;
从第24位到第48位:由各网卡制造商各自分配给自己的产品,各不重复。
有了这个名字,新的设备就能够在设备内维护一张路由表,它看起来像这样:
(其实叫做MAC地址-网段查询表)
| Mac地址 | 端口 |
|---|---|
| xx:xx:xx:xx:xx:xx | 2 |
就像写信一样,在数据包前填上来源和目标,设备就能够将数据包发送到对应端口。这样的设备叫做交换机。它可以学习所有连接到它上面的设备的Mac地址。它是这样工作的:
- 学习:若A想要向通过交换机相连接的B发送数据,则先将数据发送给交换机。交换机记录A的Mac地址
- 泛洪:若交换机不知道B的Mac地址,则向除了源端口外的所有端口转发数据包,这时由计算机来决定是否接收该数据包(根据目标mac地址)
- 转发:B接收到数据包后,会向A发送确认包。经过交换机时,交换机记录B的地址。
- 过滤:如果路由表中存在目标Mac地址对应的端口,则直接转发到对应端口。
- 老化:若记录长时间不被访问,则该记录会被清除。时间阈值可由用户配置。
路由器
当计算机的数量进一步增多,我们就需要两台以上的交换机了。来看最简单的两个交换机的情况。如果我们的目标设备在另一台交换机上,就需要将交换机中的一个端口连接到另一个交换机,先将信息发送到交换机,再发送到下一个交换机,最后到达目标计算机。这时,如何让交换机知道目标计算机是否在自己直接连接的端口上呢?
我们不妨假定,处在交换机A下的计算机用xx:xx:LL:xx:xx:xx标识,处在交换机B下的计算机用xx:xx:RR:xx:xx:xx标识。但这带来了新的问题:虽然对地址做出了区分,但代价是在路由表中,很多地址会被映射到同一个端口(这个端口就是交换机A和B之间链接的端口),就像这样:
| Mac地址 | 端口 |
|---|---|
| xx:xx:RR:xx:xx:01 | 2 |
| xx:xx:RR:xx:xx:02 | 2 |
这时,如果有一个设备能够在交换机之间工作就好了。这样一来,交换机只需要记录一个Mac地址和一个对应的端口,由中间设备帮忙转发到下一个交换机。这样的设备叫做路由器,它工作在交换机之间,能够将数据包进行一次转发。路由器的每个端口都有独立的Mac地址。但新的问题随之出现:如果有更多台交换机链接到路由器上,那么mac地址的区分方式将会更加复杂!
但我们依旧要为链接在两边的计算机的地址做出区分。网络设备出厂时的Mac地址已经被烧录,显然更改它们不是那么容易:我们必须使用其他方式给计算机添加地址了!
这时我们想到,如果用32个二进制位来表示地址,就能够给设备分配不同的地址——全看我们的需要。我们把32位地址分成4组,每组转换为10进制,就变成了我们今天常见的IP地址的形式(也叫点分十进制四组表示法):
192.168.0.1
这时,为了区分不同计算机所在的网域,我们需要把网络划分为若干个子网。子网的划分需要用到子网掩码,它的作用是告诉系统这串地址中的那部分代表网络地址,哪部分代表主机地址。当两台计算机的网络地址相同时,它们就在同一个子网下。
我们以最常见的子网掩码255.255.255.0为例。如果现在**A(192.168.1.0)发送了一个发往C(192.168.2.0)**的数据包,那么第一步当然是判断这两台计算机是否在同一个子网下。还记得吗?如果在,那么交换机就会将数据包通过自己的端口发送,如果不在,那么就必须先发往别的交换机,由其他交换机发送给目标计算机。
子网掩码的工作原理很简单,将目标IP和本机IP分别与子网掩码做与运算,运算的结果就是网络地址。如果它们相同,就证明两台计算机在同一子网下,反之则不在。路由器同的一个端口、端口连接的交换机和交换机所连接的所有计算机都处在同一个子网,也就是说,它们的IP地址与子网掩码运算后得出的网路段地址是相同的。
现在,当我们发送数据时,就需要在数据包包头里添加更多信息了:不仅有寄件人、收件人的MAC地址,还有目标IP和源IP的信息。在不妨碍你理解的前提下,这里顺带一提,MAC地址工作在数据链路层,与数据的发送和接收者具有直接的物理关系;IP地址工作在网络层,与连接和网络路径选择有强关联。回到我们的发送过程:我们先将源IP和目标IP分别与子网掩码相与,如果不在同一子网,那么A将直接把数据包发送给路由器,由路由器来发往对应的子网。在A计算机上会设置默认网关,也就是说,当A发现目标与自己不在同一子网内的时候,A会直接将数据发送给默认网关指向的设备,之后无论发生什么都由其他设备来处理。
类似地,路由器内部也会维护一张表,叫做路由表。它记录着每个不同的网段对应在哪个端口上:
| IP | 端口 |
|---|---|
| 192.168.1.X | 1 → LAN |
| 192.168.2.X | 2 → LAN |
| 0.0.0.0 | 3 → ISP服务商 |
ARP
在现实世界中,我们做不到那么神乎其神的事情:如果我要向远在北京的同学发送一条新年问候,我要先坐飞机飞往北京,打开他的手机,查看并记录他的MAC地址,再返回我家,把他的MAC地址填在目标MAC地址中。
看到这里,可能你会对上文交换机部分突然产生疑问:只有交换机和MAC地址的时代,为什么我们能够填出目标MAC地址?在那样的情景下,计算机的数量是很少的(否则交换机维护的路由表将很长很长)。这样有限的情景下,我们直接将MAC地址填在数据包中。但即使计算机数量有限,这样的行为的局限性依旧很大。
在当代生活中,我们知道的不是目标的MAC地址,而是IP地址。你所访问的www.baidu.com,www.google.com本质上都是IP地址。那么这时,除非你把电脑用数据线接在百度的机房中,否则我们都只能通过IP地址来访问这些网站。那么谁来决定目标MAC地址怎么填?和交换机的思想类似,我们需要在计算机内维护一张从IP到MAC的映射表,这叫做ARP协议。你可以在这里查看更多关于这个协议的介绍,同样能够帮助你理解这一切。
这张映射表同样会随着你发送过的目标IP变多而增大。记录着每个我们曾访问过的IP地址对应的MAC地址。当电脑发现,目标IP不在同一子网下时,会将数据发送给默认网关;这时通过ARP,数据包中的目标MAC地址会变为路由器的MAC地址,接下来的事情交给路由器处理。
下一跳
如果不能经过路由器的一次转发直接将数据发送给目标子网,那么路由器会把数据发送给另一个路由器。这时,数据在不同网域之间的移动,我们称为“一跳”。跟进一步,你和你周边的任何路由器都没有直接的线缆连接在百度的服务器的路由器上,这时该怎么办?
我们往后退一步开始:数据包发送到你的路由器,让我们假设它长这样:
源IP:192.168.1.0
目标IP: 183.2.172.177
路由器会先检查路由表,发现它不匹配任何一条存在路由表中的局域网记录。这时,路由器会将数据包发往ISP。
在发往ISP之前,路由器必须先把你的源IP变为在公网上可见的公网IP,只有这样,当数据返回时,从对方来的数据包才能通过公网找到你。这一步变换叫做NAT(网络地址转换)
BGP
你可以在这里查看更多BGP工作的细节。
经过家庭NAT后,你的数据包中的IP层会变成这样:
源IP:你的公网IP
目标IP:183.2.172.177
数据发送到ISP后,他们也会做同样的事:查找路由表,判断是否通过路由器直联,否则交给其他路由器,完成“下一跳”。不同的ISP之间通过BGP协议,维护一个记录IP路由表,来实现与其他ISP建立路由链接。
通过BGP维护的路由表,数据包会跨越各种光缆,走过数不清的路由器,最后到达由BaiDu维护的自治系统(AS)。当数据包到达百度的边缘路由器时,他会查看数据包里的内容:
目标IP:183.2.172.177
这是百度的内部网段,于是他会向内部的路由器转发,直到某一台服务器接受你的数据包。
这就是网络中数据包去往各个不同地址的全部过程。我们把链接范围扩大,加入虚拟地址与物理地址之间的映射关系表,最后还是离不开最简单的方式:把计算机用线缆连起来,就像两个连在一起的纸杯电话。