要理解网络,其实不就是理解这三张表吗

news2024/11/15 8:38:46

我们如果要理解数据是如果在网络世界中穿梭的,那其实只要了解其中的三张表就可以了。这三张表分别为路由表、转发表、ARP 表。

假设我们用聊天工具聊天的时候,我在北京,你在广东,当我给你发送一条消息的时候。搭载这这条消息的数据包需要从我的设备(电脑或手机)出发,跨域千上万水,趟过万里光纤,在不出意外的情况下才能到达你的设备。在这个过程中数据包要经过大致流程如下:

1、数据在我的设备上从应用层向下层层封装,最后发送到路由设备上;

2、路由设备对数据包进行转发,可能经过不止一个路由器和交换机;

3、终于到达你的设备所在的子网路由器,你所在的子网路由器转发给局域网内所有的直接相连的主机或交换机,如果是转发给交换机的话,交换机再次转发给交换机上连接的设备;

4、当你的设备发现这个数据包的目的主机是自己,就开始对数据包进行自链路层向上的一层一层的解封装,最终由对应的应用程序拿到消息;

主要的流程就是这样,但是中间每一种设备的转发都有对应的规则,主要涉及的设备就是终端、交换机、路由器,接下来我们具体来梳理一下一个数据包这一路上是怎么跋山涉水才呈现到你的屏幕上的。

跋山涉水来找你

看下图,假设现在「子网A的主机A」要发一条消息给「子网B的主机x-1」,这两个主机分别在不同的子网,也就是说并不是局域网内的传输,中间经过了路由器A、路由器B、子网B的顶层交换机、交换机X,最终才到达了目标主机X-1。

 

主机A封装数据包并发送

如果你已经掌握了传输层、网络层、链路层的各个协议,那这个过程就相对来说非常简单了。

应用层某聊天工具发送消息,消息内容被处理之后,也就是上图中的用户数据。

经过传输层,使用 TCP 协议传输,TCP 将用户数据封装上 TCP 首部信息,形成一个 TCP 段。注意了,TCP 首部中含有源端口号和目标端口号,应用层会根据端口号决定哪个应用程序使用这个包。比如我们自己开发的聊天程序,端口用的是 18888,那这个包到达主机X-1之后,发现 TCP 协议头中的端口号是 18888,那就知道要把这个包交给我们开发的聊天工具处理了。

经过网络层,搭载IP协议,在TCP段的基础上,加上IP首部信息,形成IP数据报。注意了,IP首部含有源IP地址和目的IP地址,要不然网海茫茫,谁来接收它,它又回复谁呢。在这个 IP 数据报中,源IP就是主机A的IP,目的 IP 地址就是主机X-1的IP。

最后经过链路层,在IP数据报的基础上,加上以太网帧首部,形成以太网帧数据包。在以太网上,只有以太网帧能顺利通行。注意了,以太网帧首部包含源MAC地址和目的MAC地址,链路层只认MAC地址,有了它才能找到对应的终端。

经过层层包装后,真正跑到以太网上的数据最终必须是一个完整的以太网帧,而以太网帧中必须要有目的端的 MAC 地址。接下来就是怎么拿到目的端的 MAC地址了。

当发送端开始组装数据的时候,首先会检查目的IP 和自身的IP 是否处在同一个网络中。计算方式很简单,就是用 IP 地址和子网掩码进行「与运算」。

如果目的端在局域网内

如果得到的网络地址是一致的,说明在同一个网络中。

这时,ARP表就要上场了。

ARP 表记录着 IP 地址和 MAC 地址的映射关系。可以根据 IP 地址查到对应的 MAC 地址,然后放到以太网帧中,如果有的话。

发送端检查自己的 ARP 表中是否有目的 IP 对应的 MAC 地址。如果有的话,直接将 MAC 地址组装到以太网数据帧中,发送数据帧,数据就能被目的端顺利接收。如果ARP 表中不存在目的IP对应的 MAC 地址,则向本网络广播发送 ARP 请求,ARP 请求会带着目的IP地址,意思就是询问“谁的IP地址是这个,请回复你的MAC地址给我”,网络中的主机看到后,如果IP是自己的,就返回给发送端一个ARP回复,回复中带着自己的MAC地址,发送端拿到MAC地址后,先存入本地的ARP表,然后组装以太网帧,将数据发送。

如果目的端不在局域网内

如果得到的网络地址不一致,说明目的端不在本网络中。那这样的话,查询 ARP表是不可能查到对应的 MAC 地址的,因为 ARP 表只存储局域网内的 IP 和 MAC 地址的映射记录。

既然查不到那怎么办,总得发出去才行啊。

如果 ARP 表中查不到记录,那只能走默认网关了。我们的设备都是知道默认网关的 IP地址的,这时候再去 ARP 表查询是否有网关地址对应的 MAC 地址,如果有直接将网关的 MAC 地址封装到以太网帧的目的地址中。如果没有的话,仍然要像上面那样,广播发送 ARP 请求,获取网关设备的 MAC 地址,然后存入 ARP 表中。对应到上图就是路由器A的端口1的网卡地址。

那将网关的 MAC 地址当做目的 MAC 地址,还怎么找到最终的目的端啊,最终的消息也不是想发给网关啊。

没办法,就是这样的,这只是第一步,在后面经过每一个非最终目的端设备的时候,都要将目的 MAC 地址设置为下一跳设备的 MAC 地址,因为以太网帧就是这样设计的。所以说,在整个传输过程中,以太网帧会不断的解析然后重新封装,目的就是把下一跳的 MAC地址封装进去。直到最终到达了目的设备所在的网络。

目的MAC 地址是一跳一跳变化的,但是 IP 头中的目的 IP 地址是绝对不能变的,要不然就真的找不到了。

路由器A如何路由的

当数据包到达路由器A之后,就要走出子网A,奔向更广阔的网络世界了。还是结合上面的图来看,这个拓扑结构还是很简单的,真实情况下,可能要经过十几二十个路由设备。

数据包来到路由器之后,路由器要怎么处理呢,路由器会进行路由操作,也就是将这个包安排一条最合适的路径发出去。

这就要提到路由表了。

路由器中维护着一张路由表,主要存放网络、主机与下一跳的对应关系。例如下表这样:

目标子网掩码下一跳网络接口
192.168.8.0255.255.255.00.0.0.0en0
114.21.1.0255.255.255.0114.21.1.100en0
0.0.0.00.0.0.0192.168.8.1en1

大致的意思就是如果收到一个数据报,在当前路由器的路由表中寻找,一般目标都是一个网络地址(标明一个子网),把具体数据包的IP地址和当前路由表的子网掩码进行与操作,如果得到的结果和路由表目标栏一直,就转发给这条记录中的下一跳地址,从网络接口栏所记录的接口发出(也就是路由器上的网口或者叫端口)。

如果下一跳地址是0.0.0.0 ,表示这个目的IP地址就在当前网络中。那就不用路由器转发了,拿到目的IP的MAC地址,就可以直接发送了(获取MAC地址的方法,前面说过了,先查ARP表,没有的话,再用ARP广播请求获取)。

如果下一跳不是0.0.0.0,表示目的IP不是本网络的地址,就发给下一跳的地址。

如果在路由表中都没有找到匹配的目标网络,那就看有没有配置默认条目了,默认条目也就是目标是0.0.0.0的条目,表示任意的IP都可以通过此条目的下一跳(也就是默认网关)地址转发出去。

如果在路由表中没有找到任何匹配的目标网络,并且没有设置默认条目,那就直接将数据包丢弃,并返回一个 主机不可达的 ICMP 请求。

路由表分为静态路由和动态路由,静态就是需要人手工配置,路由表是固定不变的,动态路由是根据一些规则动态更新路由表数据,总之, 路由表最终会有一些描述网络拓扑结构的记录存在。

当路由器A收到数据包之后,解封装这个数据包,从下层网上拆,链路层拆出 MAC 地址,发现就是自己的,继续拆,拆到 IP 层,找到目的 IP 地址,拆到 IP 层就可以了。然后拿着这个目表 IP 地址在路右边中检索,看看是否正好有对应的目标网络。

拿192.168.8.0(子网掩码是255.255.255.0)这个目标网络来说,目标是一个网络地址,可以理解为一个子网(局域网),那如果IP数据报里的目标IP是192.168.8.8/24或192.168.8.188/24都能对应上这一条记录,因为这两个地址和子网掩码与操作之后,得出的网络地址都是192.168.8.0。于是就发给下一跳 0.0.0.0。

假设我们的目标IP是114.21.1.1,通过查表发现了正好有目标地址是114.21.1.0的记录,于是转发给下一跳地址 114.21.1.100,通过en0这个接口发出去,直接发送到了与之相连的子网B的顶层交换机。

如果没有找到对应的记录,查看是否有默认路由,也就是目的地址是0.0.0.0的记录,如果有的话,就发给默认路由对应的下一跳地址。如果连默认路由也没有,直接将包丢弃,然后回复给源IP 一个类型为主机不可达的ICMP包。告诉源主机,此路不通了,然后应用程序根据这个信息,选择新的应对策略。

子网B的交换机X转发包

数据包从路由器A出来之后先到了子网B的顶层交换机,然后经过顶层交互机的转发,转发给了子网B的交换机X。顶层交换机如何转发就不说了,和交换机X的转发过程是一致的。

交换机的转发就要说到转发表了。

在交换机中维护着一张叫做转发表的映射表。一台交换机上有很多个接口,每个接口连接一台设备。转发表记录的就是接口和所连接的设备的MAC地址的映射关系。交换机就是根据这张表将数据帧传输到指定的主机端口上的。

数据包走到交换机这里了,说明它离目的地已经不远了,已经找到目标主机所在的局域网内了。

当数据包到达交互机后,交换机检查自己的MAC表是否有数据帧中目的MAC地址的匹配条目,如果有,则会根据MAC表中记录的对应端口将数据帧转发出去,这一转发方式称为「单播」。

而如果没有,则会将该数据帧从非来源端口的其它全部端口发送出去,这一转发方式程序称为「广播」。。

假设交换机 X 收到数据包后,根据目标MAC地址查询转发表,没查到,这时候,交换机X就将包从端口1和端口2广播出去给主机X-1和主机X-2,主机X-1收到这个包后,对比目的MAC地址和自己的是否一致,结果发现这个包是发给自己的,会回复交换机X一个数据包,包含自己的(主机X-1)的MAC地址,这时,交换机X就将这个MAC地址和交换机上对应的端口的映射关系记录到转发表。这一过程通常称为「自学习」。

主机X-2发现包不是发给自己的,直接就忽略了。

到此为止,主机X-1就顺利收到包了,确切的说是一个以太网帧。

子网B的主机X-1收到包之后

主机X-1收到这个数据帧之后,链路层解析,发现正好是发给自己的,因为目标MAC地址和自己的一致,然后交给网络层,发现目的IP也是自己的,于是交给传输层,传输层解析TCP段,最后将数据交给上层的应用层,应用层根据TCP的目的端口号,判断是那个应用程序要处理收到的数据。

总结

下面的流程图是对上述过程的汇总,可以点开下面的大图查看。

 

其中有几个细节要理解,对理解整个过程有很大帮助。

1、链路层的以太网数据帧必须要有目的端的 MAC 地址,而且必须是下一跳的 MAC 地址。别问为什么,协议就是这么规定的。

2、正因为链路层以太网帧必须是下一跳MAC地址,所以整个传输过程中,以太网帧是一直解包、重组的,目的就是把下一跳MAC地址重组进去。

3、网络层 IP 协议中的目的 IP地址是不能变的,那有人要问了,发送端和目的端虽然不是在一个子网中,但它们的局域网地址都是 192.168.1 网段的,那怎么能找到目的主机呢。本篇并没有讨论这个问题,这其实就要牵扯到公网和内网的映射了,一个局域网最终会映射到一个公网 IP 地址上,比如路由器可以设置 NAT 功能。

4、ARP 协议只工作在局域网中,ARP 通过 IP 获取 MAC 地址,是通过向局域网内所有主机广播 ARP  请求的,只有对应的 IP 地址才会回复这个 ARP 请求。

5、每经过一个路由设备,都要将 IP 数据报拆包,然后再重组,源IP地址设置为自己的,然后 TTL 减一,TTL 有一个限制,比如 32,当路由次数超过这个数值,表示网络环境不是很好,绕的太远了,就会把这个包丢弃掉。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/372677.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

带你沉浸式体验删库跑路

前言:学习的过程比较枯燥,后面会记录一些比较有意思的东西,比如程序员之间流传的删库跑路的梗,当然本次测试是在虚拟机上进行的并进行了快照保护,所以其实没太大问题。首先得要有一个虚拟机要有一个linux iso文件装在虚拟机上以上两点不是本文重点,如果有需要可以私…

CLIP论文阅读

Learning Transferable Visual Models From Natural Language Supervision 利用自然语言的监督信号学习可迁移的视觉模型 概述 迁移学习方式就是先在一个较大规模的数据集如ImageNet上预训练,然后在具体的下游任务上再进行微调。这里的预训练是基于有监督训练的&am…

排序基础之插入排序

目录 前言 一、什么是插入排序 二、实现插入排序 三、插入排序优化 四、插入排序的特性 前言 上一篇中我们说到了《排序基础之选择排序》,这一篇我们来学习一下排序算法中的另一种基础排序算法——插入排序。 一、什么是插入排序 简单来说就是:每…

break与continue关键字

1.概述 不知道大家有没有这样一种感受哈,有的时候容易混淆break语句和continue语句的用法,总是模棱两可,不敢确定自己是否使用正确了。正好,我们本篇的重点就是break和continue关键字的用法。 2.使用场景 Java中为啥会诞生break…

js——原型和原型链

最近看了很多面试题,看到这个js原型是常考点,于是,我总结了一些该方面的知识点分享给大家,其实原型就是那么一回事,搞明白了就没啥了。结果如下图所示:原型原型又可分为显式原型和隐式原型1.1显式原型显式原…

Linux C代码获取线程ID

Linux C代码获取线程ID gettid可以获取线程id,但是通过man gettid可以看到下面这两句 也就是说glibc没有为这个gettid封装系统调用&#xff0c;需要使用syscall。 #define _GNU_SOURCE#include <unistd.h>#include <sys/syscall.h>#include <sys/types.h>ti…

自动化测试 selenium常用操作

最简单的代码实例import org.openqa.selenium.By; import org.openqa.selenium.chrome.ChromeDriver;public class AutoTestDemo1 {//浏览器自动搜索,暂停是为了能看到&#xff0c;要不访问太快public void testKunKun() throws InterruptedException {//打开浏览器ChromeDrive…

【软件工程】课程作业(三道题目:需求分析、概要设计、详细设计、软件测试)

文章目录&#xff1a;故事的开头总是极尽温柔&#xff0c;故事会一直温柔……&#x1f49c;一、你怎么理解需求分析&#xff1f;1、需求分析的定义&#xff1a;2、需求分析的重要性&#xff1a;3、需求分析的内容&#xff1a;4、基于系统分析的方法分类&#xff1a;5、需求分析…

Java static关键字(重新认识main方法)

static关键字一、static修饰成员的特点二、static什么时候使用三、static注意事项四、重新认识main方法static 是静态的意思&#xff0c;可以修饰成员变量&#xff0c;也可以修饰成员方法 一、static修饰成员的特点 被其修饰的成员, 被该类的所有对象所共享多了一种调用方式, 可…

Vue(6)

文章目录1. 自定义指令1.1 函数式1.2 对象式1.3 自定义指令常见坑1.4 创建全局指令2. 生命周期2.1 引出生命周期2.2 分析生命周期2.3 总结3. 组件3.1 认识组件3.2 使用组件 (非单文件组件)3.3 全局组件3.4 组件的几个注意点3.5 组件的嵌套3.6 VueComponent 构造函数3.7 一个重要…

openresty学习笔记

openresty 简介 openresty 是一个基于 nginx 与 lua 的高性能 web 平台&#xff0c;其内部 集成了大量精良的 lua 库、第三方模块以及大数的依赖项。用于 方便搭建能够处理超高并发、扩展性极高的动态 web 应用、 web 服务和动态网关。 openresty 通过汇聚各种设计精良的 ngi…

LearnOpenGL-入门-纹理

本人刚学OpenGL不久且自学&#xff0c;文中定有代码、术语等错误&#xff0c;欢迎指正 我写的项目地址&#xff1a;https://github.com/liujianjie/LearnOpenGLProject LearnOpenGL中文官网&#xff1a;https://learnopengl-cn.github.io/ 文章目录纹理纹理环绕方式纹理过滤多…

3.抽象工厂模式(Abstract Factory)

与工厂模式对比 工厂模式 工厂模式是类创建模式。在工厂模式中&#xff0c;只需要生产同一种产品&#xff0c;只不过是生产厂家不同。 所以产品类的设计&#xff1a; 抽象的产品类Product具体的产品类Product_A&#xff0c;Product_B, Product_C, Product_D…… 工厂的设计…

BFC的含义以及应用

什么是BFC? BFC全称是Block Formatting context&#xff0c;翻译过来就是块级格式化上下文。简单来说&#xff0c;BFC是一个完全独立的空间。让空间里的子元素不会影响到外面的布局。&#x1f603;&#x1f603;&#x1f603; 如何触发BFC呢&#xff1f; mdn给了如下方式&a…

HMM-理论补充

目录 一.隐马尔科夫模型 二.HMM定义 三.隐马尔科夫模型的贝叶斯网络 四.HMM的确定 五.HMM的参数 六.HMM的参数总结 七.HMM的两个基本性质 1.齐次假设&#xff1a; 2.观测独立性假设&#xff1a; 八.HMM举例 九.HMM的3个基本问题 十.概率计算问题 1.直接算法 2.前向…

C语言学习笔记——程序环境和预处理

目录 前言 一、程序环境 1. 翻译环境 1.1 主要过程 1.2 编译过程 2. 运行环境 二、预处理 1. 预定义符号 2. #define 2.1 #define定义标识符 2.2 #define定义宏 2.3 命名约定和移除定义 3. 条件编译 4. 文件包含 结束语 前言 每次我们写完代码运行的时候都…

刷题28-有效的变位词

32-有效的变位词 解题思路&#xff1a; 注意变位词的条件&#xff0c;当两个字符串完全相等或者长度不等时&#xff0c;就不是变位词。 把字符串中的字符映射成整型数组&#xff0c;统计每个字符出现的次数 注意数组怎么初始化&#xff1a; int [] s1new int[26]代码如下&a…

C语言数据结构(一)—— 数据结构理论、线性表【动态数组、链表(企业版单向链表)】

数据结构理论1.1 数据数据&#xff1a;是描述客观事物的符号&#xff0c;是计算机中可以操作的对象&#xff0c;是能被计算机识别&#xff0c;并输入给计算机处理的符号集合。数据不仅仅包括整型、实型等数值类型&#xff0c;还包括字符及声音、图像、视频等非数值类型。1.2数据…

决策树、随机森林、极端随机树(ERT)

声明&#xff1a;本文仅为个人学习记录所用&#xff0c;参考较多&#xff0c;如有侵权&#xff0c;联系删除 决策树 通俗来说&#xff0c;决策树分类的思想类似于找对象。现想象一个女孩的母亲要给这个女孩介绍男朋友&#xff0c;于是有了下面的对话&#xff1a; 女儿&#x…

C++17 nodiscard标记符

文章目录前言弃值表达式nodiscard标记符函数非弃值声明类/枚举类/结构 非弃值声明返回类引用与类指针前言 在C 17中引入了一个标记符nodiscard&#xff0c;用于声明一个 “非弃值(no-discard)表达式”。那么在开始之前&#xff0c;我们需要了解一下什么是弃值表达式。 弃值表…