zoukankan      html  css  js  c++  java
  • 一文弄懂网络交换机,路由器原理

    你是一台电脑,你的名字叫A,很久很久以前,你不与任何其他电脑连接,孤苦伶仃。

    然后,你希望与另一台电脑B做朋友,两人铜线,于是你们各自开了一个网口,用一根网线连接了起来。

    用一根网线连接起来怎么就能“”通信“”了呢?这里面需要涉及到IO,终端,缓冲区等,但这不是研究网络该关心的问题。如果你想了解,可以去研究一下操作系统是如何处理网络IO的,要么去研究一下包是如何被网卡转换成电信号发送出去的,或者你就把他当做电脑里有个小人在开枪吧。

     

     反正你们就是连接起来,并且通信了。

    第一层

    有一天,有个心得伙伴C加入了,于是你们可以以每个人开两个网口,用一共三根线,彼此相连。

     但是随着越来越多的人加入,你发现身上开的网口是在太多了,而且网线密密麻麻,混乱不堪(实际上一台电脑根本开不了那么多的网口,所以这种连线只在理论上可行

     于是发明了一个中间设备,你们将网线都插到这个设备上,由这个设备做转发,就可以彼此通信了,本质上和原来一样,只不过网口的数量和网线数量减少了,不在那么混乱。

     给它取名叫加集线器,它仅仅是无脑的将电信号转发到所有出口(广播),不做任何处理,没有任何智商,因此将它定义在了“物理层”。

     由于转发到了所有出口,那么BCDE四台机器怎么知道数据包是不是发给自己的呢?

    首先,你要给所有连接到集线器的设备,都起一个名字,原来你们叫ABCD,但现在需要一个更专业的,全局唯一的名字作为标识,我们把这个更高端的名字叫做“MAC地址”。

    你的地址是 aa-aa-aa-aa-aa-aa,你的伙伴的MAC地址是bb-bb-bb-bb-bb-bb,以此类推,不重复就好。

    这样,A在发送数据包给B是,只要在头部拼接一个这样结构的数据就可以了。

     B在收到数据包后,根据头部的目标MAC地址信息,判断这个数据包的确是发给自己,于是便收下。

    其他的CDE在收到数据包后,根据头部的目标MAC地址信息,判断这个数据包并不是发给自己的,于是便丢弃。

     虽然集线器使整个布局干净不少,但原来我只要发给B的消息,现在却要发给连接到集线器中的所有电脑,这样既不安全,用不节省网络资源。

    第二层

    如果把集线器弄得更智能一些,只发给目标MAC地址指向的那台电脑,就好了。

     虽然只比集线器多了一点点区别,但看起来视乎智能了,把它叫做交换机,也正因为这一点智能,你把它放在了另一个层级,数据链路层。

     如上图所示,你是这样设计。

    交换机内部维护一样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 一个数据包,构造了如下的数据结构从网口出去。

     

     到达交换机时,交换机内部通过自己维护的MAC地址表,发现机器B的MAC地址bb-bb-bb-bb-bb-bb映射到了端口1上,于是把数据从1号端口发给了B,over完活。

    给通过这样传输方式而组成的小范围的网络,叫做以太网。

    当然最开始的时候,MAC表是空的,怎么建立起来的呢?

    假如在MAC地址表为空时,你给B发送了如下数据:

     由于这个包从端口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

     过程如下:

     经过该网络不断的通信,最终将MAC表建立完毕。

    随着电脑的数量增多,交换机网口开始不够用了,但聪明你很快发现将多个交换机连接起来,这个问题就能解决了。

     你完全不需要设计额外的东西,只需要按照之前的设计和规矩来,按照上述的接线方式即可完成所有电脑的互联,所以交换机设计的这种规则,真的很巧妙,你想想看为什么(比如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地址的设备,并且可以帮我把数据包做一次转发,把它定义在了网络层。

     注意:路由器的每一个端口,都有独立的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地址,就可以根据你规划的网络拓扑图进行调整了。

     如上图所示,假如我要发送数据包给ABCD其中的一台设备,不论哪一台,我都可以这样描述"将IP地址为192.168.0开头的全部发送给路由器,之后再怎么转发,交给路由器处理"

    那么将数据交给路由器之后,路由器有事怎么把数据包转却转发给指定设备呢?

    我们献给上面的组网方式中每台设备,加上自己的IP地址。

     现在两个设备之间传输,除了加上数据链路层的头部之外,还要再加一个网络层的头部。加入A给B发送数据,由于他们直接连着交换机,所有A直接将数据发送给B,这时网络层IP是不体现作用的。

     但是假如A发给C,A需要先将数据转发给路由器,然后再有路由器将数据转发给C。由于最底层传输依然需要依赖以太网,所以数据包分成两段。

    A~路由器这段内容的包如下:

     路由器到 C 这段的包如下:

     上面说的两种情况(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 也不在同一个子网,以此类推。

     

    所以。A给C发消息,A和C的IP地址分别&A机器配置的子网掩码,发现不相等,则A与C不在同一个子网,于是A将数据包发送给路由,就不管了。

    A如何知道,哪个设备是路由呢?

    上一步A通过是否与C在同一个子网内,判断自己应该把包发给路由器,那路由器的IP是多少呢?其实说发给路由器并不准确,应该说发给默认网关。

    对于A来说,A只能将包发送给同处于一个子网下的某个IP上,所以发给路由器还是发给某台电脑,对A来说也不关心,只要这个设备有IP地址就可以了。

    所以默认网关,就是A在自己电脑里配置的一个IP地址,以便A在发给不同子网的机器时,发送给这个IP地址。

    问题又来了,包发送到路由器之后,又是如何将包发送给C的呢?

    答案:路由表

    A将包成功发送给路由器后,路由器怎么知道收到的这个包,从自己的那个端口出去,才能最终到达目的地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.

    需要注意的是,刚才都是在说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的MAC地址,将会广播一条arp请求,B收到请求后,带上自己的MAC地址给A一个响应,此时A便更新了自己的arp表。

    这样通过不断的arp广播请求,最终所有电脑里面都将arp缓存表更新完整。

    总结:

    从各个节点来看

    电脑视角:

    首先我们要知道我的IP和对方的IP。

    通过子网掩码判断我们是否在一个子网。

    在同一个子网就通过arp获取对方mac地址直接扔出去。

    不在同一个子网就通过arphuoqu默认网关的mac地址扔出去。

    交换机视角:

    我们收到的数据包必须有目标MAC地址

    通过MAC地址表查映射关系

    查到了就按照映射关系从我的按指定端口f发出去。查不到就所有端口都发出去。

    路由器视角:

    我收到的数据包必须有目标IP地址

    通过路由表查映射关系

    查到了就按照映射关系从指定的端口发出去(不在任何一个子网范围内,走路由器默认网关也是查到了)

    查不到则返回一个路由不可达的数据包

    通过以上你可以看出:

    网络层(IP协议)本身米有传输包的功能,包的实际传输是交给数据链路层(以太网中的交换机来完成的)

    涉及到的三张表:

    交换机中的MAC地址表,用于映射MAC地址表和它的端口。

    路由器中的路由表,用于映射IP地址(段)和它的端口

    电脑和路由器中都有的arp缓存表用于缓存IP与MAC地址的映射关系

    三张表的由来:

    MAC地址表通过以太网内各节点之间不断地通过交换机通信,逐渐完善起来的。

    路由表是由各种路由算法+人工配置起来的。

    arp缓存表是不断通过arp协议的请求逐渐完善起来的。

    通过以上学习,目前网络上两个节点如何发送数据包的过程就可以解释通了。

    下面是一张网络拓扑图。

    这时路由器 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 发送一个数据包,能不能通呢?如果通的话整个过程是怎样的呢?

     详细过程动画描述:

    详细过程文字描述:

    1.首先A(192.168.0.1)通过子网掩码计算出自己与F(192.168.2.2)并不在一个子网内,于是决定发送给默认网关(192.168.0.254)

    2.A通过arp协议找到默认网关的MAC地址

    3.A将源MAC地址(AAAA)与网关MAC地址(ABAB)封装在数据链路层头部,又将源IP(192.168.0.1)和网关(192.168.0.254)封装在网络层头部,然后发包。

    4.交换机收到数据包后,发现目标MAC地址ABAB,将其转发给路由器1.

    5.数据包来到了路由器后,发现目标ip是192.168.2.2,通过查路由表,发现下一跳IP192.168.100.5。

    6.所以此时路由器需要再次匹配路由表,发现匹配到了端口2,于是将其封装在数据链路层,将包从端口2发出去。

    7.此时数据包来到了路由器2,看到其目标IP192.168.2.2,查询其路由表,匹配到端口号1,备将包从端口1发送出去。

    8.但此时路由器2需要知道192.168.2.2的MAC地址了,所以查看其arp缓存找MAC地址,将其封装在数据链路层头部,并从1号端口发送出去。

    9.交换机3此时收到了数据包,发现了其目标MAC地址为FFFF,查询其MAC地址表,于是将数据从6端口发出去。

    10.F最终收到了数据包,并且发现MAC目标地址就是自己,于是收下了此包。

    到此,经过物理层,数据链路层,网络层这三层的协议,以及根据这些协议涉及的设备(网线,集线器,交换机,路由器),理论上只要拥有对方的IP地址,就已经将网络中任意两个连通。

  • 相关阅读:
    1553: Good subsequence (很奇妙的set模拟题,也可以直接暴力)
    1550: Simple String (做得少的思维题,两个字符串能否组成另外一个字符串问题)
    1549: Navigition Problem (几何计算+模拟 细节较多)
    1548: Design road (思维题 做法:三分找极值)
    Python 正则表达式入门(初级篇)
    Python中的正则表达式教程
    软件自动化测试的学习步骤
    自动化测试的Selenium的python版安装与使用
    自动化测试一些问题
    自动化测试
  • 原文地址:https://www.cnblogs.com/liushui0306/p/14601168.html
Copyright © 2011-2022 走看看