文章持续更新,可以微信搜一搜「golang小白成长记」第一时间阅读,回复【教程】获golang免费视频教程。本文已经收录在GitHub https://github.com/xiaobaiTech/golangFamily , 有大厂面试完整考点和成长路线,欢迎Star。
故事就从一个车轱辘说起吧。先来看一个车轱辘。
辐条从车轱辘边缘,一直汇聚到 中心的轴,这个轴在英文里叫hub。
而我们今天要讲到的集线器,英文里也叫hub。
都叫hub,多少有点关系,看下这面这个图大概能明白,其实两者有点像。
大概想表达的意思是,它是汇聚网线的中心,因此就叫集线器。
所以可以理解,大家常逛的 Github,Docker Hub, 还有Phub ,都是为了表达它们是某类资源的中心**了吧。
那么集线器是什么呢?那就要从电脑是怎么互联的这个话题说起。
小学的时候,有一种网吧,它其实是不能上外网的。也就是不能打开度娘,不能搜索资料。
不能上网的网吧还能叫网吧?
能。虽然不能上外网,但网吧老板可以把很多台机子连起来,实现网吧内互联,形成一个局域网(Local Area Network,简称LAN)。
网吧内互联之后,就可以放上各种游戏,比如CS,实现网吧内对线。
这种网吧有种好处,没有那么多键盘侠。
毕竟你不知道什么时候键着键着,对方就顺着网线找过来了。
对战直接从线上转移到线下了。
因此大家打游戏都很和谐,客气,场面十分感人就是了。
那么网吧内的电脑是怎么互联呢?
一根网线互联电脑
从最简单的场景说起,假设网吧内只有两台电脑
随便连根网线就能实现互联吗?
当然不是。
还记得网络分层吗?
数据如果要进行传输,会从A电脑经过这些网络分层把消息组装好,再到B电脑层层解包。
网线,只是代替了上面的灰色部分,实现物理层上互联。
如果想要两台电脑互联成功,还需要确保每一层所需要的步骤都要做到位,这样数据才能确保正确投送并返回。
我们自顶向下,从细节开始说一下实现互联需要做什么。
应用层
该层的网络功能由应用本身保证。
假设两台电脑是打算用游戏进行联网,那么该应用层的功能由游戏程序保证。
传输层
绝大部分游戏用的传输层协议都是TCP,我们可以看下TCP报头。
这里面我们需要关注的是源和目的端口,这个可以定位到这台电脑上哪个进程在收发数据。
这两个端口信息一般是游戏内部已经填好。
AB两台电脑,其中一台作为服务端启动,比如A,起了个服务器进程。
服务器会开放一个固定的端口,比如27015。这就是目的端口。
这时候A和B都可以搜索到这个服务器。启动一个客户端进程,连接进入A的服务器进程。
而源端口,则由A和B自己生成。
网络层
上图除了端口,我们还看到一个192.168.0.105
,这个就是A的IP地址。
我们看一下IP层的报文头。
这里面需要关注是源和目的IP地址。
如果两台电脑想通过一根网线进行消息通信,那么他们需要在一个局域网内。
这意味着,他们的子网掩码需要一致。局域网内,假设子网掩码是 225.225.225.0
,会认为 192.168.0.x
这些IP都属于一个局域网。所以当A的IP地址是192.168.0.105
时,那么B的IP地址可以配成192.168.0.106
。
关于IP这一块是啥,后面会细讲,大家如果没明白我说的是啥,不要急。
组装好网络层报头后,数据包传入到数据链路据层。
数据链路层
以上解决了网络层的互联,而在数据链路层,数据包里需要拼接上MAC报头。先看下MAC报头长什么样子。
其中需要关心的是标红的源和目的MAC地址。MAC地址可以粗略理解是这台电脑网卡的唯一标识。大概长这样
28:f9:d3:62:7d:31
源和目的地址,在发送消息的时候就会被填上。
但是A只知道自己的MAC地址,怎么才能知道B的MAC地址呢?
这时候需要ARP协议。
ARP(Address Resolution Protocal),即地址解析协议。用于将IP地址解析为以太网的MAC地址的协议。
在局域网中,当主机A有数据要发送给主机B时,A必须知道B的IP地址。
但是仅仅有IP地址还是不够的,因为IP数据报文还需要在数据链路层封装成帧才能通过物理网络发送。因为发送端还必须有接收端的MAC地址,所以需要一个从IP地址到MAC地址的映射。ARP就是干这事情的协议。
- A查本地ARP表发现B的IP和MAC映射关系不存在
- A通过ARP广播的形式向局域网发出消息,询问某IP对应的MAC地址是多少。比如A此时知道B的IP,但并不知道B的MAC地址是多少,就会尝试在局域网内发起ARP广播,询问局域网下所有机器,哪个机器的IP与B的IP一致。
- B收到这个ARP消息,发现A要问的IP与自己的IP一致,就会把自己的MAC地址作为应答返回给A。
- 此时A就知道了B的MAC地址,顺便把消息记录到本地ARP表里,下次直接用表里的关系就行,不需要每次都去问。
物理层
从数据链路层到物理层,数据会被转为01比特流。
此时需要把比特流传到另一台电脑。
通过一根网线,两段水晶头插入网口,把两台电脑连起来。
但对网线有一些要求。
这根网线两端的水晶头需要采用交叉互联法。
水晶头里有8根线,注意上图里的颜色,是有顺序的。第1、2根线起着收信号的作用,而第3、6脚发信号的作用。将一端的1号和3号线、2号和6号线互换一下位置,就能够在物理层实现一端发送的信号,另一端能收到。
当然,现在有些网卡有自适应的功能,就算是直连互联法的线,也能有交叉互联法的效果。如果你用的是这种网卡,就当我物理层这块什么都没说吧。
互联
此时,在确保关闭防火墙的前提下,可以尝试从A电脑中ping一下B,再从B电脑中ping一下A。如无意外,都能ping通。
A给B发个消息,从应用层到数据链路层,会分别加上A和B的各种''身份信息"。比如在传输层会加上A和B的应用端口号,在网络层加上源和目的IP,在数据链路层会加上源和目的网卡的MAC头部信息。
B收到消息后逐层解包,验证,最后顺利到达应用层。实现AB两台机器消息互通。
至此游戏就能正常联机对线,两台电脑互联成功!
什么是集线器
两个人打cs,总会觉得无聊,但是每台电脑又只有一个网线口。
想要邀请更多的人一起玩,怎么办?
那就要回到文章开头提到的集线器(hub)了。
这是个工作在物理层的设备。
有多个网口,很好的解决了电脑上只有一个网口的问题,可以做到多台电脑的网线都插入到集线器上。
同时工作原理也非常简单,会把某个端口收到的数据,输入到中继电路。
中继电路的基本功能是将输入的信号广播到集线器的所有端口上。
简单来说就是无脑复制N份到其余N个端口上。
数据复制到N个端口后。对应转发到N台机器里。
集线器内部结构
说到这里,已经对集线器有个大概认识了。
接下来,我们看下集线器的内部结构。
从A网口进入集线器的消息,此时还是电信号。这里经过一个PHY模块。
要理解PHY模块的作用,首先要先了解每个网口,都可能接着网线(废话),而每根网线的传输的格式都是有可能不同的。而PHY的作用,就是把这些格式转化为一个通用的格式。
举个例子。PHY就好比一个翻译器,有的人说英文,有的人说日文。但是PHY,会把它统一转为普通话,给内部电路处理。内部电路处理完之后,再经过PHY模块,转为英语,或日文从对应网口里输出。
经过PHY的处理后,以电信号的形式输入到中继电路,被无脑广播,再次经过PHY模块后变成BCD网口的格式输出。
这里面的电信号,是会受噪声干扰,导致信号形变出错的。
但就算是错了,也还是会原封不动的广播出去,这就是上面提到无脑的精髓所在。
那信号如果出错了怎么办?
只能让接收方收到消息后进行校验。
还记得上文里提到的数据链路层的MAC报头里最末尾有个FCS吗?
FCS里存放的是发送方通过循环冗余校验CRC计算得到的值。
接收方用收到的数据算一次CRC,与FCS里的值进行对比。
如果一致,那证明数据没问题。如果出错,则直接丢弃。
当然,丢弃包并不会影响数据的传输, 因为丢弃的包不会触发确认响应。因此协议栈的 TCP 模块会检测到丢包, 并对该包进行重传。
如果消息没出错,但是因为无脑广播,C也能收到A发给B的数据包。
此时 C 会在接受到数据包后一层层的"剥开"。
正常情况下,在数据链路层时,识别到目的 MAC 地址跟 C 的不一致时,也会把数据丢弃。
什么是交换机
目前只有 ABC 三台机器,每次都是广播发消息倒还好。
如果机器越来越多,每台机器发一条消息,都会被广播,就有点顶不住了。
举个例子。
假设N台机器,其中两台机器A和B,A发到B和B发给A,共两条消息。
如果这N台机器,用的是集线器。还是AB之间互发消息,每条消息都是广播的话,就是(N-1)+(N-1)条消息,差距有些大,对网络资源浪费就有些严重了。
那么,有没有可能做到,A发给B的消息,就不要转发给C呢?
可以的,把集线器换成交换机。
交换机,又叫switch,跟集线器长得很像。
但是功能更强一些,从网络分层上来说,属于数据链路层,比集线器所在的物理层还要高一层。
所有发到交换机的数据,都会先进入交换机的缓存区。接着消息再被转发到对应机器上。
注意这里用的是转发,而不是集线器的广播,交换机是怎么做到转发的呢?
MAC地址表
交换机内部维护了一张MAC地址表。
记录了 端口号和MAC地址的对应关系。
这个表的数据是交换机不断学习的结果。
当A发消息到交换机时,交换机发现消息是从1号端口进来的,则会在MAC地址表上,记录A的MAC地址对应1号端口。
如果A没有很长时间没发消息到这个1号端口,那这条记录就会过期并被删除。
那么,当时间足够长,ABC 都发过消息给交换机后,地址表就会有完整的关系信息。
- A准备发送消息给B,此时A会把B的MAC地址,放入要发送的数据里。数据顺着网线发出。
- 交换机从端口收到数据,会把数据里的源和目的MAC地址提出来,跟MAC地址表进行对比。
- 发现B的MAC地址正好在2号端口,那么就把数据转发给2号端口。
- 此时B电脑从网线收到来自交换机2号端口的数据。
两种特殊情况
正常流程很清楚了,看两个特殊情况:
- 交换机查询地址表时,发现目的 MAC 地址的目标端口和这个包的源端口,是同一个端口,怎么办?
先说结论,会直接丢弃这个包。
我们看下,假设它不丢弃,会发生什么情况。
- A发了个消息给B,中间经过一个集线器,此时消息会被广播到B和交换机。
- 此时B收到第一条A发给它的消息
- 交换机从1号端口收到A的消息后,解包,获得目的MAC地址是BB-BB-BB-BB-BB-BB。查MAC地址表,发现要发到1号端口。此时,源和目的端口都是同一个,如果交换机不丢弃这个消息,B会收到第二条A发给它的消息。
A只发了一次消息,B却收到两条消息,明显不对。
因此,当交换机查询地址表时,发现目标端口和源端口,是同一个端口时,会丢弃这个包。
- MAC地址表里找不到对应的MAC地址,怎么办?
这可能是因为具有该地址的设备,还没有向交换机发送过包,或者这个设备一段时间没有工作,导致地址被从地址表中删除了。
这种情况下,交换机无法判断应该把包转发到哪个端口,只能将包转发到除了源端口之外的所有端口上,无论该设备连接在哪个端口上,都能收到这个包。
此时,交换机就会跟集线器一样进行广播。
发送了包之后目标设备会作出响应,只要返回了响应包,交换机就可以将它的地址写入地址表,下次也就不需要把包 发到所有端口了。
交换机内部结构
再看下交换机内部结构。
其实对比可以发现,交换机和集线器内部结构很像。
重点需要提到的是MAC模块。消息以电信号的形式从网口进入,到了PHY会被转成通用格式的电信号。而MAC模块的作用是把这个电信号转为数字信号,这样就能提取出MAC包头,并通过MAC数据帧末尾的FCS校验这个包有没有问题,如果没问题,则把数据放到内存缓冲区里,否则直接丢弃。
另外,这个MAC模块,虽然这么叫。但其实交换机MAC模块不具有 MAC 地址。因此交换机的端口不核对接收方 MAC 地址,而是直接接收所有的包并存放到缓冲区中。
放入到内存缓冲区后,还会把MAC地址和端口号记录到MAC地址表中。同时检查目的MAC地址在不在MAC地址表中,在的话则会转发到对应端口。否则广播。
交换机与网桥的区别
网桥,本质上可以理解为两个网线口的交换机,正好可以把两台电脑给连起来,也叫桥接。而交换机,则是多网线口的网桥,可以把多台电脑给连(桥接)起来。
其他功能方面,大差不差,不必太过纠结。
交换机和二层交换机和三层交换机有什么区别
这一部分提到的交换机,其实就是二层交换机,也就是工作在第二层(数据链路层)的交换机,二者没区别。
而三层交换机,是工作在第三层(网络层)的交换机,其实就是接下来要提到的路由器。
什么是路由器
有了交换机之后,小网吧里的电脑就都可以被连起来了。交换机网口不够?那就再接个交换机。
但世界上电脑这么多,交换机里的MAC地址表难道全都要记住吗?
显然做不到。为了解决这个问题。
于是就有了路由器,工作在网络层,比数据链路层更高一层。
网络层引入了IP的概念。
什么是IP
比如前面提到的 192.168.0.105
就是一个IP,同一个局域网内还可能会有一个IP是192.168.0.106
。有没有发现,它们都是192.168.0.xxx
。
像极了 上海市.黄浦区.南京东路.105号
,这样的地址。现实生活中,我们可以通过一个地址定位到要去哪。到了 上海市.黄浦区.南京东路.105号
楼里,我们就可以再去找某个叫身份证为xiaobaixxxxx
的人。
那互联网世界里,我们也就可以通过IP地址,定位到某个广域网段,再通过广域网内部的局域网的MAC地址定位到具体某个电脑。
上海市.黄浦区.南京东路.105号
可以帮助我们定位到在南京东路上的第105号楼的位置。但还有些路,比如南京西路,可能不止105号,可能要到257号。
实际上一个IP由网络号和主机号组成,共32位组成。如果拿了前面24位做网络号,那主机号就剩8位了,2的8次方=256,最多表示表示256号楼。因此为了多表示几个楼,可以向网络号多挪几位过来作为主机号。
那么具体多少位作为网络号呢?可以在IP后面加一个数字,用来表明这一点。
于是就有了 192.168.0.105/24
这种表示方法,表明前24位192.168.0.0
是网络号,105是主机号。
有了网段,就可以一次性表示一大批地址。就不需要像交换机那样苦哈哈的一条一条MAC地址记录在表里。
路由表
路由器的作用,可以帮助我们在互联网世界里转发消息到对应的IP。
对比一下。
交换机,是通过 MAC 头部中,接收方 MAC 地址,来判断转发目标的。
路由器,则是根据 IP 头部中, IP 地址来判断的。
由于使用的地址不同,记录转发信息的表也会不同。
类似交换机的MAC地址表,路由器也维护了一张路由表。
而路由表,是用于告诉路由器,什么样的消息该转发到什么端口。
假设A要发消息到D。也就是192.168.0.105/24
要发消息到192.168.1.11/24
。
那么A会把消息经过交换机发到路由器。
路由器通过192.168.0.105/24
获得其网络号是 192.168.0.0
,而目的地的网络号是192.168.1.0
,二者网络号不同,处于不同局域网。
查路由表,发现192.168.1.0
,在e2端口,那么就会把消息从e2端口发出,到达交换机,交换机发现MAC地址是它局域网下的D机器,就把消息打过去。
当然,如果路由表里找不到,那就打到默认网关吧,也就是从e1口发出,发到IP192.0.2.1
。这个路由器的路由表不知道该去哪,说不定其他路由器知道。
路由器的内部结构
路由器内部,分为控制平面和数据平面,说白了就是对应软件部分和硬件部分。
硬件部分跟交换机很像。数据从A网口进入,此时数据还是网线上格式的电信号,会被PHY模块转为通用信号格式,再被MAC模块转为数字信号,通过FCS进行错误校验,同时校验MAC地址是否是自己,通过校验则进入内存缓冲区,否则丢弃。
再进入软件部分,由路由选择处理器,通过一定规则(软件逻辑),查询路由表判断转发目标和对应转发口,再经由硬件部分的交换结构转发出去。
如果路由表中无法找到匹配记录,路由器会丢弃这个包,并通过ICMP消息告知发送方。
路由器和交换机的主要区别
MAC模块的区别
路由器和交换机不同点在于,它的每个网口下,都有一个MAC地址和IP地址。
正因为路由器具有 MAC 地址,因此它能够成为数据链路层的的发送方和接收方。
怎么理解这句话?
前面提到交换机,是不具备MAC地址的,而MAC报头是需要填上目的MAC地址的。因此交换机从来都不是数据的目的地,它只简单转发数据帧到目的地。
但路由器,是有MAC地址的,因此MAC报头就可以写上,下一站目的地就是xx路由。
到了路由器后,路由器可以再次组装下一站的目的MAC地址是再下一个路由,通过这一点,让数据在路由和路由之间传输。
而同时因为交换机不具有MAC地址,因此也不会校验收到的数据帧的MAC地址是不是自己的,全部收下做转发。而路由器则会校验数据帧的MAC报头里的目的MAC地址是不是自己,是的话才会收入内存缓冲区,否则丢弃。
找不到转发目的地时的处理方式有区别
如果在路由表中无法找到匹配的记录,路由器会丢弃这个包,并通过 ICMP消息告知发送方。
而交换机在MAC地址表里找不到转发端口时会选择广播。
这里的处理方式两者是不同的,原因在于网络规模的大小。
交换机连接的网络最多也就是几千台设备的规模,这个规模并 不大。如果只有几千台设备,遇到不知道应该转发到哪里的包,交换机可以将包发送到所有的端口上,虽然这个方法很简单粗暴,但不会引发什么 问题。
但路由器工作的网络环境就是互联网,全世界所有的设备都连接在互联网上,规模非常大,并且这个规模还在持续扩大中。如果此时它的操作跟交换机一样,将不知道应该转发到哪里的包发送到整个网络上,那就会产生大量的网络包,造成网络拥塞。因此,路由器遇到不知道该转发到哪里的包, 就会直接丢弃。
路由器和光猫有什么区别
不管是交换机还是路由器,前面都是提到网口输入的是电信号。但现在流行的是光纤传输,传输的是光信号。
而光猫(modem),是一种调制解调器,其实就是用于光电信号转换的设备。
接收数据时,可以将光纤里的光信号转化为电信号,发给路由器,路由器内部再转成数字信号,并在此基础上做各种处理。
相反,也会把路由器传来的电信号转为光信号,发到光纤,并进入互联网。
总结
- 两台电脑可以通过一根网线直接连接,进行通信。
- 机器一多,可以把网线都接到集线器(物理层)上,但是集线器会不管三七二十一进行广播。
- 不想广播,可以用(二层)交换机(数据链路层),又叫多端口网桥,它比较聪明,会自我学习生产MAC地址表,知道消息发到哪,那就不需要广播啦
- 互联网电脑这么多,交换机MAC地址表总不能全放下吧。改用路由器(网络层),也叫三层交换机,通过网段的方式定位要把消息转发到哪,就不需要像交换机那样苦哈哈一条条记录MAC地址啦。
- 路由器和光猫之间是好搭档,光猫负责把光纤里的光信号转换成电信号给路由器。
- 现在一般情况下,家里已经不用集线器和交换机了,大部分路由器也支持交换机的功能。所以可以看到,家里的台式机电脑一般就连到一个路由器,再连个光猫就够能快乐上网了。
最后
以前整个班的同学家里都不见得有一台电脑,都喜欢偷偷跑去网吧玩电脑。改革开放的春风,把电脑吹进了每家每户,也把网吧给吹成了网咖。
从前的我晚上偷偷上网,现在的我,接到报警,也能在大半夜爬起来网上冲浪。
没想到我以这种方式保持了当初最纯粹的质朴。
我是小白,看下右下角,你懂我意思的。
夏天快来了,我们下期见。
参考资料
网络是怎么连接的 - 户根勤
趣谈网络协议- 极客时间
文章推荐:
别说了,一起在知识的海洋里呛水吧
关注公众号:【golang小白成长记】