从网线到网络设备
从网线到网络设备
总结:
主要介绍通过网线传输出去的包是如何经过集线器、交换机和路由器等网络设备,最终进入互联网的。重点是路由器,
集线器:中继电路 + 多个 PHY(MAU) 模块 +RJ-45 接口
交换机:交换电路 + 多个网卡(ROM+MAC 模块 +PHY(MAU) 模块 +RJ-45 接口)
路由器:包转发模块(IP 模块)+ 端口模块(多个支持不同网络协议类型的网卡)
第三章跟第二章有很多地方都相互对应了,就像是第二章的原理的实际应用一样。
信号在网线和集线器中传输
每个包都是独立传输的
无论包里面装的是应用程序的数据或者是 TCP 协议的控制信息,都不会对包的传输操作本身产生影响。换句话说,HTTP 请求的方法,TCP 的确认响应和序号,客户端和服务器之间的关系,这一切都与包的传输无关。因此,所有的包在传输到目的地的过程中都是独立的,相互之间没有任何关联。
我们假设客户端计算机连接的局域网结构是像图 3.1 这样的。也就是说,网络包从客户端计算机发出之后,要经过集线器、交换机和路由器最终进入互联网。实际上,我们家里用的路由器已经集成了集线器和交换机的功能,这里,我们把每个功能独立出来更容易理解。
防止网线中的信号衰减很重要
本章的探索从信号流出网卡进入网线开始。网卡中的 PHY(MAU)模块负责将包转换成电信号,信号通过 RJ-45 接口进入双绞线,这部分的放大图如图 3.2 的右侧部分所示。以太网信号的本质是正负变化的电压,大家可以认为网卡的 PHY(MAU)模块就是一个从正负两个信号端子输出信号的电路。
但是,信号到达集线器的时候并不是跟刚发送出去的时候一模一样。集线器收到的信号有时会出现衰减(图 3.3)。信号在网线的传输过程中,能量会逐渐损失。网线越长,信号衰减就越严重。
即便线路条件很好,没有噪声,信号在传输过程中依然会发生失真,如果再加上噪声的影响,失真就会更厉害。
集线器的中继电路有放大信号的作用(我猜的)。
" 双绞 " 是为了抑制噪声
局域网网线使用的是双绞线,其中 " 双绞 " 的意思就是以两根信号线为一组缠绕在一起,这种拧麻花一样的设计是为了抑制噪声的影响。
那么双绞线为什么能够抑制噪声呢?这里讲了很多电磁波的知识,没有必要深究
集线器将信号发往所有线路
基础知识:
集线器有多个 RJ-45 接口,RJ-45 接口用于连接水晶头,也就是说集线器会同时连接多个水晶头。
每一条信号传输线路都有正负两个信号端子,也就是说发送一个信号需要两条线,发送线路有两个端子,接受线路也有两个端子。
PHY(MAU) 和 RJ-45 的接口的接法有两种 MDI/MDI-X,MDI 就是对 RJ-45 接口和 PHY(MAU) 的信号收发模块进行直连接线(PHY(MAU) 的发送端子接发送接口,PHY(MAU) 的接收端子接接收接口),而 MDI-X 则是交叉接线(对 RJ-45 接口和 PHY(MAU) 的信号收发模块进行反向接线,PHY(MAU) 的发送端子接接收接口,PHY(MAU) 的接收端子接发送接口)。信号如果要正常传输,就必须从 PHY(MAU) 的发送线路发出,出发经过网线,从另一个网卡的 PHY(MAU) 的接受线路进入网卡,也就是说,一头用 MDI 直接连线,另一头必须用 MDI-X 交叉接线,看图 3.2
信号到达集线器的 PHY(MAU)模块后,会进入中继电路。中继电路的基本功能就是将输入的信号广播到集线器的所有端口上。接下来,信号从所有接口流出,到达连接在集线器上的所有设备。然后,这些设备在收到信号之后会通过 MAC 头部中的接收方 MAC 地址判断是不是发给自己的,如果是发给自己的就接受,否则就忽略。这样,网络包就能够到达指定 MAC 地址的接收方了。
交换机的包转发操作
交换机根据地址表进行转发
首先,信号到达网线接口,并由 PHY(MAU)模块进行接收,这一部分和集线器是相同的。也就是说,它的接口和 PHY(MAU)模块也是以 MDI-X 模式进行连接的,接下来,PHY(MAU)模块会将网线中的信号转换为通用格式,然后传递给 MAC 模块。MAC 模块将信号转换为数字信息,然后通过包末尾的 FCS 校验错误,如果没有问题则存放到缓冲区中。这部分操作和网卡接受信号的处理流程基本相同,可以认为交换机的每个网线接口后面都是一块网卡。网线接口和后面的电路部分加在一起称为一个端口,也就是说交换机的一个端口就相当于计算机上的一块网卡。换句话说,如果在计算机上安装多块网卡,并开启 " 混杂模式 " 让网卡接收所有的网络包,然后再安装一个和交换机具备同样功能的网络包转发软件,那么这台计算机就变成了一台交换机(一般电脑上至少有两个网卡,一个是以太网网卡,一个是无线局域网网卡)。但交换机的工作方式和网卡有一点不同:交换机的端口不核对接收方 MAC 地址,而是直接接收所有的包并存放到缓冲区中。因此,交换机端口的 MAC 模块不具有 MAC 地址。将包存入缓冲区后,接下来需要查询一下这个包的接收方 MAC 地址是否已经在 MAC 地址表中有记录了。MAC 地址表主要包含两个信息,一个是设备的 MAC 地址,另一个是该设备连接在交换机的哪个端口上。以图 3.7 中的地址表为例,MAC 地址和端口是一一对应的,通过这张表就能够判断出收到的包应该转发到哪个端口。然后就可以通过交换电路将包发送到相应的端口了。
注意:从工作原理来看,交换机的端口和网卡很像,但实际上并非如图上这样每一个端口都有独立的 PHY(MAU)、MAC 和内存,一般都是通过一个控制芯片同时控制多个端口。
交换电路的结构如图 3.8 所示,它可以将输入端和输出端连接起来。其中,信号线排列成网格状,每一个交叉点都有一个交换开关,交换开关是电子控制的,通过切换开关的状态就可以改变信号的流向。交换电路的输入端和输出端分别连接各个接收端口和发送端口,网络包通过这个网格状的电路在端口之间流动。
MAC 地址表的维护
第一种是收到包时,将发送方 MAC 地址以及其输入端口的号码写入 MAC 地址表中。
另一种是删除地址表中某条记录的操作,这是为了防止设备移动时产生问题。然而,交换机没办法知道这台笔记本电脑已经从原来的端口移走了。因此地址表中的记录不能永久有效,而是要在一段时间不使用后就自动删除。计算机网络的时效性非常短,因此很多缓存的数据都会有一个过期时间。
总之,交换机会自行更新或删除地址表中的记录,不需要手动维护。当地址表的内容出现异常时,只要重启一下交换机就可以重置地址表,也不需要手动进行维护。
特殊操作
-
交换机查询地址表之后发现记录中的目标端口和这个包的源端口是同一个端口,这种情况要怎么处理呢?处理方法是,当交换机发现一个包要发回到原端口时,就会直接丢弃这个包。
-
地址表中找不到指定的 MAC 地址。这可能是因为具有该地址的设备还没有向交换机发送过包,或者这个设备一段时间没有工作导致地址被从地址表中删除了。这种情况下,交换机无法判断应该把包转发到哪个端口,只能将包转发到除了源端口之外的所有端口上,这就跟集线器的操作一样了,结果就是只有相应的接收者才接收包,而其他设备则会忽略这个包。等目标设备会作出响应,只要返回了响应包,交换机就可以将它的地址写入地址表,下次也就不需要把包发到所有端口了。
-
如果接收方 MAC 地址是一个广播地址,那么交换机会将包发送到除源端口之外的所有端口。
PS:广播地址(broadcast address)是一种特殊的地址,将广播地址设为接收方地址时,包会发送到网络中所有的设备。MAC 地址中的 FF:FF:FF:FF:FF:FF 和 IP 地址中的 255.255.255.255 都是广播地址。
全双工模式可以同时进行发送和接收
使用集线器时,如果多台计算机同时发送信号,信号就会在集线器内部混杂在一起,进而无法使用,这种现象称为碰撞,是以太网的一个重要特征。
而使用双绞线时,发送和接收的信号线是各自独立的,因此在双绞线中信号不会发生碰撞。网线连接的另一端,即交换机端口和网卡的 PHY(MAU)模块以及 MAC 模块,其内部发送和接收电路也是各自独立的,信号也不会发生碰撞。因此,只要不用集线器,就可以避免信号碰撞了。如果不存在碰撞,也就不需要半双工模式中的碰撞处理机制了。也就是说,发送和接收可以同时进行。然而以太网规范中规定了在网络中有信号时要等该信号结束后再发送信号,因此发送和接收还是无法同时进行。于是,人们对以太网规范进行了修订,增加了一个无论网络中有没有信号都可以发送信号的工作模式,同时规定在这一工作模式下停用碰撞检测(图 3.10)。这种工作模式就是全双工模式。在全双工模式下,无需等待其他信号结束就可以发送信号,因此它比半双工模式速度要快。由于双方可以同时发送数据,所以可同时传输的数据量也更大,性能也就更高。
全双工模式是交换机特有的工作模式,(在交换机内部)它可以同时进行发送和接收操作,集线器不具备这样的特性
意思是,硬件上,从 MAC 模块到 PHY(MAU) 模块到 RJ-45 接口(RJ-45 接口的发送线路和接受线路本来就是分开的),本来就是支持同时发送信号和接受信号的,只是集线器不能同时处理多个输入信号。现在有了交换机,配合硬件,完全不会有信号碰撞,因此就可以同时发送信号和接受信号。
CSMA/CD 中说得情况被双绞线解决了
半双工模式中,AB 通信,A 发了信号,B 再发,也就是说 A 发信号的时候,B 得等着,但是全双工模式中,AB 可以同时给对方发信号。
自动协商:确定最优的传输速率
在全双工模式刚刚出现的时候,还需要手动进行切换,但这样实在太麻烦,于是后来出现了自动切换工作模式的功能。这一功能可以由相互连接的双方探测对方是否支持全双工模式,并自动切换成相应的工作模式。此外,除了能自动切换工作模式之外,还能探测对方的传输速率并进行自动切换。这种自动切换的功能称为自动协商。
在以太网中,当没有数据在传输时,网络中会填充一种被称为连接脉冲的脉冲信号。在没有数据信号时就填充连接脉冲,这使得网络中一直都有一定的信号流过,从而能够检测对方是否在正常工作,或者说网线有没有正常连接。以太网设备的网线接口周围有一个绿色的 LED 指示灯,它表示是否检测到正常的脉冲信号。如果绿灯亮,说明 PHY(MAU)模块以及网线连接正常。
后来,人们又设计出了如图 3.11 这样的具有特定排列的脉冲信号,通过这种信号可以将自身的状态告知对方。自动协商功能就利用了这样的脉冲信号,即通过这种信号将自己能够支持的工作模式和传输速率相互告知对方,并从中选择一个最优的组合。
下面来看一个具体的例子。假设现在连接双方的情况如表 3.2 所示,网卡一方支持所有的速率和工作模式,而交换机只支持到 100Mbit/s 全双工模式。当两台设备通电并完成硬件初始化之后,就会开始用脉冲信号发送自己支持的速率和工作模式。当对方收到信号之后,会通过读取脉冲信号的排列来判断对方支持的模式,然后看看双方都支持的模式有哪些。表 3.2 是按照优先级排序的,因此双方都支持的模式就是第 3 行及以下的部分。越往上优先级越高,因此在本例中 100 Mbit/s 全双工模式就是最优组合,于是双方就会以这个模式开始工作。
交换机可同时执行多个转发操作
交换机只将包转发到具有特定 MAC 地址的设备连接的端口,其他端口都是空闲的。如图 3.7 中的例子所示,当包从最上面的端口发送到最下面的端口时,其他端口都处于空闲状态,这些端口可以传输其他的包,因此交换机可以同时转发多个包。
这里讲的是多个端口可以同时工作,而 本章:全双工模式可以同时进行发送和接收
中的全双工模式讲的是一个端口在全双工模式下可以同时发送和接收信号。
路由器的包转发操作
路由器的基本知识
网络包经过集线器和交换机之后,现在到达了路由器,并在此被转发到下一个路由器。这一步转发的工作原理和交换机类似,也是通过查表判断包转发的目标。不过在具体的操作过程上,路由器和交换机是有区别的。因为路由器是基于 IP 设计的(基于 IP 地址转发),而交换机是基于以太网设计的(基于 MAC 地址转发)。
路由器包括转发模块和端口模块两部分。其中转发模块负责判断包的转发目的地,端口模块负责包的收发操作。转发模块和端口模块的关系,就相当于协议栈的 IP 模块和网卡之间的关系。因此,大家可以将路由器的转发模块想象成 IP 模块,将端口模块想象成网卡。(路由器跟交换机不一样,交换机只相当于交换电路 + 多个网卡)
通过更换网卡,计算机不仅可以支持以太网,也可以支持无线局域网,路由器也是一样。如果路由器的端口模块安装了支持无线局域网的硬件,就可以支持无线局域网了。此外,路由器的端口模块则支持除局域网之外的多种通信技术,如 ADSL、FTTH,以及各种宽带专线等,只要端口模块安装了支持这些技术的硬件即可。(以太网、无线局域网、以及 ADSL、FTTH,以及各种宽带专线等,都是不同的网络技术,需要特定的硬件支持,路由器同时支持这些网络技术,就会涉及到网络包在不同的网络协议之间过渡的问题,比如从以太网进入,发送到无线局域网,这其中的一个问题就是输出端口的最大包跟输入端口的不一样,就需要分片,详细请看 本章:通过分片功能拆分大网络包
)(一般的个人电脑上至少会有两个网卡,一个以太网网卡,一个无线网卡,这两个网卡都有自己的 MAC 地址,在 Windows 系统上通过 ipconfig /all
查看所有的网络接口即网卡信息,也可以用前面提到的 route print
命令查看)
路由器的基本原理:
路由器在转发包时,首先会通过端口将发过来的包接收进来,这一步的工作过程取决于端口对应的通信技术。对于以太网端口来说,就是按照以太网规范进行工作,而无线局域网端口则按照无线局域网的规范工作,总之就是委托端口的硬件将包接收进来。接下来,转发模块会根据接收到的包的 IP 头部中记录的接收方 IP 地址,在路由表中进行查询,以此判断转发目标。然后,转发模块将包转移到转发目标对应的端口,端口再按照硬件的规则将包发送出去,也就是转发模块委托端口模块将包发送出去的意思。
刚才我们讲到端口模块会根据相应通信技术的规范来执行包收发的操作,这意味着端口模块是以实际的发送方或者接收方的身份来收发网络包的。以以太网端口为例,路由器的端口具有 MAC 地址,因此它就能够成为以太网的发送方和接收方。端口还具有 IP 地址,从这个意义上来说,它和计算机的网卡是一样的。当转发包时,首先路由器端口会接收发给自己的以太网包,然后查询转发目标,再由相应的端口作为发送方将以太网包发送出去。这一点和交换机是不同的,交换机只是将进来的包转发出去而已,它自己并不会成为发送方或者接收方(交换机的网卡没有 MAC 地址)。
路由表中的信息
路由表中的 IP 地址只包含表示子网的网络号部分的比特值(配合子网掩码),而表示主机号部分的比特值全部为 0。路由器会将接收到的网络包的接收方 IP 地址与路由表中的目标地址进行比较,并找到相应的记录。交换机在地址表中只匹配完全一致的记录,而路由器则会忽略主机号部分,只匹配网络号部分。打个比方,路由器在转发包的时候只看接收方地址属于哪个区,××区发往这一边,××区发往那一边。这样效率更高
特殊情况:
-
路由聚合
目标地址列中的 IP 地址表示的是子网,但也有一些例外,有时地址本身的子网掩码和路由表中的子网掩码是不一致的,这是路由聚合的结果。路由聚合会将几个子网合并成一个子网,并在路由表中只产生一条记录。
我们现在有 3 个子网,分别为10.10.1.0/24、10.10.2.0/24、10.10.3.0/24,路由器 B 需要将包发往这 3 个子网。在这种情况下,路由器 B 的路由表中原本应该有对应这 3 个子网的 3 条记录,但在这个例子中,无论发往任何一个子网,都是通过路由器 A 来进行转发,因此我们可以在路由表中将这 3 个子网合并成10.10.0.0/16,这样也可以正确地进行转发,但我们减少了路由表中的记录数量,这就是路由聚合。
-
具体的计算机的地址
我们也可以将某台具体计算机的地址写入路由表中,这时的子网掩码为 255.255.255.255,也就是说地址中的全部 32 个比特都为 1。
从结果上看,路由表的子网掩码列只是用来在匹配目标地址时告诉路由器应该匹配多少个比特(这个总结太精髓了)。而且,目标地址中的地址和实际子网的网络号可能并不完全相同,但即便如此,路由器依然可以正常工作。按照这样的规则,我们可能会匹配到多条候选记录。其中,路由器首先寻找网络号比特数最长的一条记录。网络号比特数越长,说明主机号比特数越短,也就意味着该子网内可分配的主机数量越少,即子网中可能存在的主机数量越少,这一规则的目的是尽量缩小范围,所以根据这条记录判断的转发目标就会更加准确。有时候路由表中会存在网络号长度相同的多条记录,例如考虑到路由器或网线的故障而设置的备用路由就属于这种情况。这时,需要根据跃点计数的值来进行判断。跃点计数越小说明该路由越近,因此应选择跃点计数较小的记录。如果在路由表中无法找到匹配的记录,路由器会丢弃这个包,并通过 ICMP 消息(第二章:将服务器的响应包从 IP 传递给 TCP
小节介绍过)告知发送方。
跃点计数,它表示距离目标 IP 地址的距离是远还是近。这个数字越小,表示距离目的地越近;数字越大,表示距离目的地越远。
这一小节的内容解决了 第二章:生成包含接收方 IP 地址的 IP 头部
小节的疑惑。
路由表记录维护的方式和交换机也有所不同。交换机中对 MAC 地址表的维护是包转发操作中的一个步骤(在接受到包的时候把发送方 MAC 地址和包输入端口的记录到 MAC 地址表中),而路由器中对路由表的维护是与包转发操作相互独立的,也就是说,在转发包的过程中不需要对路由表的内容进行维护。对路由表进行维护的方法有几种,大体上可分为以下两类。
-
由人手动维护路由记录,比如
本章:从互联网访问公司内网
小节中将内网服务器映射到外网的配置。 -
根据路由协议机制,通过路由器之间的信息交换由路由器自行维护路由表的记录,这些路由协议有很多种,例如 RIP、OSPC、BGP 等都属于路由协议。这里就不深究了。TODO
路由器的包接收操作
路由器的端口有各种不同的类型,这里我们只介绍以太网端口是如何接收包的。首先,信号到达网线接口部分,其中的 PHY(MAU)模块和 MAC 模块将信号转换为数字信息,然后通过包末尾的 FCS 进行错误校验,如果没问题则检查 MAC 头部中的接收方 MAC 地址,看看是不是发给自己的包,如果是就放到接收缓冲区中,否则就丢弃这个包。
查询路由表确定输出端口
完成包接收操作之后,路由器就会丢弃包开头的 MAC 头部。MAC 头部的作用就是将包送达路由器,其中的接收方 MAC 地址就是路由器端口的 MAC 地址。因此,当包到达路由器之后,MAC 头部的任务就完成了,于是 MAC 头部就会被丢弃。
接下来,路由器会根据 MAC 头部后方的 IP 头部中的内容进行包的转发操作。
如图 3.13 的情况,假设地址为 10.10.1.101 的计算机要向地址为 192.168.1.10 的服务器发送一个包,这个包先到达图中的路由器。判断转发目标的第一步,就是根据包的接收方 IP 地址查询路由表中的目标地址栏,以找到相匹配的记录。就像前面讲过的一样,这个匹配并不是匹配全部 32 个比特,而是根据子网掩码列中的值判断网络号的比特数,并匹配相应数量的比特。按照这样的规则,我们可能会匹配到多条候选记录。比如这个例子中第 3、4、5 行都可以匹配。其中,路由器首先寻找网络号比特数最长的一条记录。网络号比特数越长,说明主机号比特数越短,也就意味着该子网内可分配的主机数量越少,即子网中可能存在的主机数量越少,这一规则的目的是尽量缩小范围,所以根据这条记录判断的转发目标就会更加准确。因此这里应该选择第 4 行作为转发目标。按照最长匹配原则筛选后,如果只剩一条候选记录,则按照这条记录的内容进行转发。然而,有时候路由表中会存在网络号长度相同的多条记录,例如考虑到路由器或网线的故障而设置的备用路由就属于这种情况。这时,需要根据跃点计数的值来进行判断。跃点计数越小说明该路由越近,因此应选择跃点计数较小的记录。如果在路由表中无法找到匹配的记录,路由器会丢弃这个包,并通过 ICMP(第二章:将服务器的响应包从 IP 传递给 TCP
小节介绍过)消息告知发送方。这里的处理方式和交换机不同(交换机是发送到所有端口,相当于广播),原因在于网络规模的大小。交换机连接的网络最多也就是几千台设备的规模,这个规模并不大。广播到所有端口不会引发什么问题。然而,路由器工作的网络环境就是互联网,它的规模是远远大于以太网的,如果将不知道应该转发到哪里的包发送到整个网络上,那就会产生大量的网络包,造成网络拥塞。因此,路由器遇到不知道该转发到哪里的包,就会直接丢弃。
找不到匹配路由时选择默认路由
如果找不到匹配的端口,那么是不是所有的转发目标都需要配置在路由表中才行呢?这样太麻烦了,我们的做法是配置默认路由,比如图 3.13 路由表中的最后一行。
这一行的子网掩码为 0.0.0.0,关键就在这里,子网掩码 0.0.0.0 的意思是网络包接收方 IP 地址和路由表目标地址的匹配中需要匹配的比特数为 0,换句话说,就是根本不需要匹配。只要将子网掩码设置为 0.0.0.0,那么无论任何地址都能匹配到这一条记录,这样就不会发生不知道要转发到哪里的问题了。而且由于匹配的比特数越长优先级越高(最长匹配原则),因此子网掩码为 0.0.0.0 的记录优先级是最低的,只有当找不到其他匹配的记录时,才会选择这条记录。(一个简单的规则的花式应用,真的很聪明)
只要在这一条记录的网关列中填写接入互联网的路由器地址,当匹配不到其他路由时,网络包就会被转发到互联网接入路由器。因此这条记录被称为默认路由,这一行配置的网关地址被称为默认网关。在计算机的 TCP/IP 设置窗口中也有一个填写默认网关的框,意思是一样的。

包的有效期
从路由表中查找到转发目标之后,网络包就会被转交给输出端口,并最终发送出去,但在此之前,路由器还有一些工作要完成。比如更新 IP 头部中的 TTL(Time to Live,生存时间)字段(参见 第二章:生成包含接收方 IP 地址的 IP 头部
小结中的表 2.2)。TTL 字段表示包的有效期,包每经过一个路由器的转发,这个值就会减 1,当这个值变成 0 时,就表示超过了有效期,这个包就会被丢弃。这个机制是为了防止包在一个地方陷入死循环。发送方在发送包时会将 TTL 设为 64 或 128,也就是说包经过这么多路由器后就会 " 寿终正寝 "。现在的互联网即便访问一台位于地球另一侧的服务器,最多也只需要经过几十个路由器,因此只要包被正确转发,就可以在过期之前到达目的地。
为什么只需要经过几十个路由器?我们可以通过 tracert 命令查看从当前地址到目标 IP 到底需要经过多少个路由器。
Windows 端用 tracert
可以看到从电信内网到阿里云服务器,只需要经过 12 个路由器的转发。
Linux 端用 traceroute,如果没有的话,用 yum install traceroute 一个即可。
traceroute/tracert 的基本原理:
traceroute 最简单的基本用法是:traceroute hostname
traceroute 程序的设计是利用 ICMP 及 IP header 的 TTL(Time To Live)栏位(field)使用过 UDP 协议。首先,traceroute 送出一个 TTL 是 1 的 IP datagram(其实,每次送出的为 3 个 40 字节的包,包括源地址,目的地址和包发出的时间标签)到目的地,当路径上的第一个路由器(router)收到这个 datagram 时,它将 TTL 减 1。此时,TTL 变为 0 了,所以该路由器会将此 datagram 丢掉,并送回一个「ICMP time exceeded」消息(包括发 IP 包的源地址,IP 包的所有内容及路由器的 IP 地址),traceroute 收到这个消息后,便知道这个路由器存在于这个路径上,接着 traceroute 再送出另一个 TTL 是 2 的 datagram,发现第 2 个路由器......。traceroute 每次将送出的 datagram 的 TTL 加 1 来发现另一个路由器,这个重复的动作一直持续到某个 datagram 抵达目的地。
当 datagram 到达目的地后,该主机并不会送回 ICMP time exceeded 消息,因为它已是目的地了,那么 traceroute 如何得知目的地到达了呢?traceroute 在送出 UDP datagrams 到目的地时,它所选择送达的 port number 是一个一般应用程序都不会用的号码(30000 以上),所以当此 UDP datagram 到达目的地后该主机会送回一个「ICMP port unreachable」的消息,而当 traceroute 收到这个消息时,便知道目的地已经到达了。所以 traceroute 在 Server 端也是没有所谓的 Daemon 程式。
traceroute 提取发 ICMP TTL 到期消息设备的 IP 地址并作域名解析。每次,traceroute 都打印出一系列数据,包括所经过的路由设备的域名及 IP 地址,三个包每次来回所花时间。
tracert 命令详解
https://www.jianshu.com/p/2895909c1b54x
通过分片功能拆分大网络包
路由器的端口并不只有以太网一种,也可以支持其他局域网或专线通信技术。不同的线路和局域网类型各自能传输的最大包长度(MTU)也不同,当包在不同的通信技术之间流转的时候,输出端口的最大包长度可能会小于输入端口,这个时候就需要使用 IP 协议中定义的分片功能对包进行拆分,缩短每个包的长度。可回看 第二章:生成包含接收方 IP 地址的 IP 头部
中的细节。
最大包长度是由各个通信规格定义的,如果包超过了这个最大长度就不符合相应的规格,也就不能传输了,因此输入端口收到的包不会超过最大长度。所有通信技术的最大包长度(MTU)的定义都是一样的,都是指 IP 包:IP 头部 +(IP) 数据,数据层可以是 TCP 头 +(TCP) 数据,也可以是 UDP 头 +(UDP) 数据,这就是分出 IP 层的好处,回看 第二章:生成包含接收方 IP 地址的 IP 头部
小节。
分片操作的过程如图 3.15 所示。首先,我们需要知道输出端口的 MTU,看看这个包能不能不分片直接发送。最大包长度是由端口类型决定的,用这个最大长度减掉头部的长度就是 MTU,(在以太网中,这个头部就是 MAC 头部),将 MTU 与要转发的包长度进行比较。如果输出端口的 MTU 足够大,那么就可以不分片直接发送;如果输出端口的 MTU 太小,那么就需要将包按照这个 MTU 进行分片,但在此之前还需要看一下 IP 头部中的标志字段,确认是否可以分片。一般来说都是可以分片的,但下面两种情况不能分片:1)发送方应用程序等设置了不允许分片;2)这个包已经是经过分片后的包。如果查询标志字段发现不能分片,那么就只能丢弃这个包,并通过 ICMP 消息通知发送方。否则,就可以按照输出端口 MTU 对数据进行依次拆分了。在分片中,TCP 头部及其后面的部分都是可分片的数据,尽管 TCP 头部不属于用户数据,但从 IP 来看也是 TCP 请求传输的数据的一部分。数据被拆分后,每一份数据前面会加上 IP 头部,其大部分内容都和原本的 IP 头部一模一样,但其中有部分字段需要更新,这些字段用于记录分片相关的信息。涉及到的参数主要有标识符(Identifier)、标记(Flags)、片偏移(Fragment Offset)具体可回看 第二章:生成包含接收方 IP 地址的 IP 头部
小节。
路由器的发送操作和计算机相同
在将包发送出去之前实际上还有一项工作。IP 头部中有一个用于错误检验的字段 " 校验和 ",在路由器更新 TTL 和分片的过程中,IP 头部的内容发生了改变,因此必须重新计算校验和。这里之所以没有详细讲解这个过程,是因为和以太网以及通信线路本身的错误校验机制相比,IP 校验和的可靠性很低,因此大多数路由器都不去校验这个值,就当它不存在一样。
到这里,发送前的准备工作就完成了,接下来就会进入包的发送操作。这一步操作取决于输出端口的类型。如果是以太网端口,则按照以太网的规则将包转换为电信号发送出去;如果是 ADSL 则按照 ADSL 的规则来转换,以此类推。这里,我们假设路由器位于公司等局域网的内部,即输出端口也是以太网,看看这种情况是如何操作的。
基本过程和协议栈中的 IP 模块发送包的过程是基本上是相同的(回看 第二章:IP 与以太网的包收发操作
整个小节),协议栈中的 IP 模块会设置包的 IP 头部和 MAC 头部,设置其中的一些字段,然后将完成的包转换成电信号并发送出去。但是。路由器的转发只用重新设置 MAC 头部,IP 头部中的发送地址和接收地址是不需要也是不能修改的。(本章:地址转换的基本原理
小节中,地址转换设备会修改 IP 和端口,这数据特殊情况)。
首先,为了判断 MAC 头部中的接收方的 MAC 地址应该填写什么值,我们需要根据路由表的网关列判断对方的地址。如果网关是一个 IP 地址,则这个 IP 地址就是我们要转发到的目标地址;如果网关为空,则 IP 头部中的接收方 IP 地址就是要转发到的目标地址。第二章:生成包含接收方 IP 地址的 IP 头部
小结我们讲过网关的 IP 地址和接口的 IP 地址相同时,表示 IP 头部中的接收方 IP 地址就是我们要转发的直接目标。路由器和 Windows 不一样,当包可以直接发送到最终接收方时,一般网关列是留空的。知道对方的 IP 地址之后,接下来需要通过 ARP 根据 IP 地址查询 MAC 地址,并将查询的结果作为接收方 MAC 地址。路由器也有 ARP 缓存,因此首先会在 ARP 缓存中查询,如果找不到则发送 ARP 查询请求。确定接收方 MAC 地址之后,接下来是发送方 MAC 地址字段,这里填写输出端口的 MAC 地址(注意,路由器的端口都是有自己的 IP 和 MAC 地址的)。还有一个以太类型字段,填写 0080(十六进制),表示 IP 协议。
网络包完成后,接下来会将其转换成电信号并通过端口发送出去。这一步的工作过程和计算机也是相同的。如果输出端口为以太网,则发送出去的网络包会通过交换机到达下一个路由器。由于接收方 MAC 地址就是下一个路由器的地址,所以交换机会根据这一地址将包传输到下一个路由器。接下来,下一个路由器会将包转发给再下一个路由器,经过层层转发之后,网络包就到达了最终的目的地。
路由器与交换机的关系
计算机在发送网络包时,或者是路由器在转发网络包时,都需要在前面加上 MAC 头部。之前的讲解都是说在开头加上 MAC 头部,如果看图 3.16 大家可以发现,准确的说法应该是将 IP 包装进以太网包的数据部分中。也就是说,给包加上 MAC 头部并发送,从本质上说是将 IP 包装进以太网包的数据部分中,委托以太网去传输这些数据。
IP 协议本身没有传输包的功能,因此包的实际传输要委托以太网来进行。路由器是基于 IP 设计的,而交换机是基于以太网设计的,因此 IP 与以太网的关系也就是路由器与交换机的关系。换句话说,路由器将包的传输工作委托给交换机来进行。当然,这里讲的内容只适用于原原本本实现 IP 和以太网机制的纯粹的路由器和交换机,实际的路由器有内置交换机功能的,比如用于连接互联网的家用路由器就属于这一种,对于这种路由器,上面内容可能就不适用了(" 路由器将包的传输工作委托给交换机来进行 " 这个说法其实很容易混淆,理解这个意思即可)。但是,如果把这种 " 不纯粹 " 的路由器拆分成 " 纯粹 " 的路由器和 " 纯粹 " 的交换机,则它们各自都适用上面的内容。
简单来说,IP 负责将包发送给通信对象这一整体过程,而其中将包传输到下一个路由器的过程则是由以太网来负责的。
当然,网络并非只有以太网一种,还有无线局域网,以及接入互联网的通信线路,它们和 IP 之间的关系又是什么样的呢?其实只要将以太网替换成无线局域网、互联网线路等通信规格就可以了。IP 本身不负责包的传输,而是委托各种通信技术将包传输到下一个路由器,这样的设计是有重要意义的,即可以根据需要灵活运用各种通信技术,这也是 IP 的最大特点。正是有了这一特点,我们才能够构建出互联网这一规模巨大的网络。
这一小节的内容其实就是我在 第二章:包的基本知识
小节中自己总结的内容。
路由器的附加功能
两种最重要的功能 ------ 地址转换和包过滤。
通过地址转换有效利用 IP 地址
随着接入互联网的设备越来越多,全世界的 IP 地址不够用了,需要解决这个问题
解决这个问题的关键在于固定地址的分配方式。举个例子,假如有 A、B 两家公司,它们的内网是完全独立的。这种情况下,两家公司的内网之间不会有网络包流动,即使 A 公司的内网中的某台服务器和 B 公司的内网中的某台客户端具有相同的 IP 地址也没关系,因为它们之间不会进行通信。只要在每家公司自己的范围内,能够明确判断网络包的目的地就可以了。即公司内部设备的地址不一定要和其他公司不重复。
当然,就算是公司内网,也不是可以随便分配地址的,因此需要设置一定的规则,规定某些地址是用于内网的,这些地址叫作私有地址,而原来的固定地址则叫作公有地址,在内网中可用作私有地址的范围仅限以下这些。
10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255
这些地址属于公有地址中还没有分配的范围。换句话说,私有地址本身并没有什么特别的结构,只不过是将公有地址中没分配的一部分拿出来规定只能在内网使用它们而已。
尽管这样的确能节省一部分地址,但仅凭这一点还无法完全解决问题。公司内网并不是完全独立的,而是需要通过互联网和其他很多公司相连接,所以当内网和互联网之间需要传输包的时候,问题就出现了,因为如果很多地方都出现相同的地址,包就无法正确传输了,(A 公司的内网和 B 公司的内网是不会有包流动的,但是内网跟互联网还是有包流动的,不然不就成了离线网了嘛)。
当公司内网和互联网连接的时候,需要采用图 3.17 这样的结构,即将公司内网分成两个部分,一部分是对互联网开放的服务器,另一部分是公司内部设备。其中对互联网开放的部分分配公有地址,可以和互联网直接进行通信,这一部分和之前介绍的内容是一样的。相对地,内网部分则分配私有地址,内网中的设备不能和互联网直接收发网络包,而是通过一种特别的机制进行连接,这个机制就叫地址转换。具体细节看 本章:地址转换的基本原理
小节
地址转换的基本原理
地址转换的基本原理是在转发网络包时对 IP 头部中的 IP 地址和 TCP 头部或者 UDP 头部中的端口号进行改写。
首先,TCP 连接操作的第一个包被转发到互联网时,会像图 3.18 这样,将发送方 IP 地址从私有地址改写成公有地址。这里使用的公有地址是地址转换设备的互联网接入端口的地址(具备地址转换功能的设备不仅有路由器,有些防火墙也有地址转换功能,它的工作方式和路由器是相同的,在当前文档中将其理解为路由器即可)。与此同时,端口号也需要进行改写,地址转换设备会随机选择一个空闲的端口。然后,改写前的私有地址和端口号,以及改写后的公有地址和端口号,会作为一组相对应的记录保存在地址转换设备内部的一张表中。改写发送方 IP 地址和端口号之后,包就被发往互联网,最终到达服务器,然后服务器会返回一个包。服务器返回的包的接收方是原始包的发送方,因此返回的包的接收方就是改写后的公有地址和端口号。这个公有地址其实是地址转换设备的地址,因此这个返回包就会到达地址转换设备。接下来,地址转换设备会从地址对应表中通过公有地址和端口号找到相对应的私有地址和端口号,并改写接收方信息,然后将包发给公司内网,这样包就能够到达原始的发送方了。在后面的包收发过程中,地址转换设备需要根据对应表查找私有地址和公有地址的对应关系,再改写地址和端口号之后进行转发。当数据收发结束,进入断开阶段,访问互联网的操作全部完成后,对应表中的记录就会被删除。(我猜应该是通过超时来关闭的)
在 软件工程师需要了解的网络知识:从铜线到 HTTP | 高并发的哲学原理 小节中,也提到了这一点,摘抄如下:
一台计算机所拥有的 ip 地址和子网掩码配合,让这台计算机认识到了自己的局域网的范围在哪儿。我们采用家用网络中最常见的
192.168.1.2/255.255.255.0
的配合来解释它的作用:
192.168.1.2
是本机的 ip,也是判定某个 ip 是不是局域网 ip 的基础
255.255.255.0
的意思是前三段保持一致,最后一段 0-255 都是局域网 ip换句话说就是
192.168.1.0
-192.168.1.255
都是和本机一个局域网的计算机那判断目标 ip 是不是同一个局域网有什么用呢?
- 如果要连接的是局域网内的
192.168.1.3
,那么连接方式将是:
发送 ARP 请求得到该 ip 地址对应的 MAC 地址
将数据包上 TCP 首部、IP 首部(目标 ip 地址
192.168.1.3
)、以太网首部(目标地址是192.168.1.3
的 MAC 地址),发送给交换机交换机会直接将这个包发到目标计算机所在的网口上
- 如果要连接的是
114.114.114.114
这个 ip,那么本机就会将这个包发给网关192.168.1.1
:
发送 ARP 请求得到网关的 MAC 地址
将数据包上 TCP 首部(目标端口 80,源端口 20000)、IP 首部(目标 ip 地址
114.114.114.114
,源 ip 地址192.168.1.2
)、以太网首部(目标地址是192.168.1.1
的 MAC 地址),发送给交换机交换机会直接将这个包发到网关所在的网口上
网关收到了这个以太网帧,进行层层解包:
目标 MAC 地址是自己,说明这个包是合法的
IP 首部中的目标 ip 地址不是自己,说明这是一个需要网关进行转发的数据包,接着进入转发流程:
TCP 首部中,目标端口 80 不会变,但是源端口 20000 指的是
192.168.1.2
这台计算机的源端口,在网关192.168.1.1
上这个端口已经被别的局域网机器用过了,该怎么办?修改端口将 TCP 首部中的源端口改为 50000,将 IP 首部中的源 ip 地址改为本路由器的 WAN 口 ip,即公网 ip,发送出去。我们假设本路由器的公网 ip 为
106.0.0.1
。此时网关设备的内存里已经建立起了一个映射:50000 端口对应的是内网的
192.168.1.2
的 20000 端口,当来自114.114.114.114
80 端口的 IP 包到达时,同样将目标 ip 地址从106.0.0.1
改为192.168.1.2
,目标端口 从 50000 改为 20000,发送到局域网交换机上,再由交换机进行以太网帧转发。
现在我懂了,为什么要在内网中使用互联网中没有使用过的 IP 地址,因为地址转换设备同时连接了内网和互联网,如果内网中使用的地址是互联网中已经使用了的公有 IP,那么地址转换设备在转发接收方为这个 IP 的包的时候,就会冲突,不知道是往互联网转发还是往内网转发,所以如果内网使用的 IP 跟互联网使用的 IP 一开始就是分开的,就不会有这个问题。
对内网地址的转发信息只在这台地址转换设备上记录了,所以所有流量都得通过这台地址转换设备转发。
改写端口号的原因
只改 IP 的话,有多少台设备要上互联网,就需要多少个公有地址。内网同时使用的人数一多,就需要很多公有地址,改写端口号正是为了解决这个问题。端口号是一个 16 比特的数值,总共可以分配出 65536 个端口(有很多端口都是保留端口,不是所有端口都能用于地址转换),也就是最多支持这么多内网设备,明显效率更高。
从互联网访问公司内网
对于从公司内网访问互联网的包,即便其发送方私有地址和端口号没有保存在对应表中也是可以正常转发的,因为用来改写的公有地址就是地址转换设备自身的地址,而端口号只要随便选一个空闲的端口就可以了,这些都可以由地址转换设备自行判断。然而,对于从互联网访问公司内网的包,如果在地址转换设备的对应表中没有记录就无法正常转发。因为如果对应表中没有记录,就意味着地址转换设备无法判断公有地址与私有地址之间的对应关系。换个角度来看,这意味着对于没有在访问互联网的内网设备,是无法从互联网向其发送网络包的。而且即便是正在访问的设备,也只能向和互联网通信中使用的那个端口发送网络包,无法向其他端口发送包。也就是说,除非公司主动允许,否则是无法从互联网向公司内网发送网络包的。这种机制具有防止非法入侵的效果。
不过,有时候我们希望能够从互联网访问公司内网,这需要进行一些设置才能实现。之所以无法从互联网访问内网,是因为对应表里没有相应的记录,那么我们只要事先手动添加这样的记录就可以了(图 3.19)。一般来说,用于外网访问的服务器可以放在地址转换设备的外面并为它分配一个公有地址,也可以将服务器的私有地址手动添加到地址转换设备中,这样就可以从互联网访问到这台具有私有地址的服务器了。同时还需要将地址转换设备的公有地址添加到 DNS 服务器中,不然互联网无法找到地址转换设备。
这就像是将内网中的设备映射到外网让外网访问一样,这一点在公司中经常使用,比如我在公司内网部署了一套 OA,或者一个 SVN 服务器,员工们需要在公网环境下可以自由访问,在地址转换设备的对应表中添加一个映射信息即可,非常方便。
路由器的包过滤功能
包过滤就是在对包进行转发时,根据 MAC 头部、IP 头部、TCP 头部的内容,按照事先设置好的规则决定是转发这个包,还是丢弃这个包。我们通常说的防火墙设备或软件,大多数都是利用这一机制来防止非法入侵的。(防火墙,防的其实就是网络包)