当前位置: 首页 > ops >正文

Linux:网络层IP协议

如果通信双方在同一局域网内,可直接通过数据链路层进行相互通信(通过MAC地址寻址)。

但是不同局域网之间无法直接相互通信,原因在于MAC地址是“扁平”且“无意义”的:MAC地址(如 00-1A-2B-3C-4D-5E)只是一个设备的唯一硬件标识符。它不包含任何关于这个设备位于哪个网络的信息。就像一个人的身份证号只标识了“你是谁”,但没有告诉你“你在哪个国家、哪个城市”。这时就需要一个统一的寻址和路由系统,将各个局域网连接起来,形成一个更庞大的“互联网”——这就是网络层的作用

本文我们先介绍IP地址及如何通过IP地址进行路由,随后会介绍IP协议的报头

子网掩码

IP 地址有32位,分为两个部分, 网络号和主机号

网络号:标识了这个IP地址属于哪个特定的网络。就像邮寄地址中的“城市和街道”。

主机号:标识了在这个特定网络中的哪一台设备。就像邮寄地址中的“门牌号”。

每一个IP都标识一台唯一的网络设备,但是它并不是与该设备绑定的,换一个网段,该设备的IP就会发生变化(当然这个工作一般不是由用户来做的)。

现在的问题在于,如何知道IP地址哪部分是网络号,哪部分是主机号呢?(也就是如何合理划分IP地址,使其能够被充分利用,网络号过长,则能容纳的设备就变少;主机号过长,就可能因为实际设备远远小于可容纳设备的上限而浪费IP地址)

为此,早期的人们把IP地址分为了五类:

随着互联网的飞速发展,这种划分方案的局限性很快显现出来,大多数组织都申请B类网络地址, 导致 B类地址很快就分配完了, 而 A 类却浪费了大量地址。归根结底,还是这种粗粒度的划分不够精细,不能适应实际需求

为了解决IP地址被浪费的问题,又在原方案的基础上引入了子网掩码概念:

设立子网掩码的目的:更灵活地划分IP地址,确定IP地址中哪一部分是网络号

子网掩码也是32位,实际的网络号=子网掩码&IP地址,一个网段下的所有设备的子网掩码相同

这样一来,一个网段到底可以容纳多少台设备(即主机号有多少位)也可以通过设置子网掩码被更精细地设置,而不是像原来一样被粗糙的分为五类

这里举例演示一下:

按照原来划分五类的标准,A所在的网段192.168.1最多可容纳256台设备,但实际可能只有十几台设备,这显然没有充分利用IP地址;

而引入子网掩码以后,A和B的前24位IP地址相同,但实际网络号却不相同,A的网络号是IP地址后24位,而B的网络号则是27位;

这里最后还要说明一点:127.xxx.xxx.xxx的 IP 地址用于本机环回测试(即自己和自己进行通信),通常是 127.0.0.1

NAT

要注意的是,子网掩码只是提供了一种更合理更充分利用IP地址的方式,它并没有创造新的IP地址;IP地址一共只有32位,那么这意味着最多只有2^32个IP地址,大概43亿。显然,即使充分利用了所有的IP地址,对于高速发展的互联网而言还是远远不够。为了解决IP地址不足的问题,又诞生了NAT技术。当然在介绍NAT之前,我们还需引入一个概念:私网IP和公网IP

私有IP和公有IP

私有IP:在私有网络内部(如家庭、公司、学校局域网)自由使用的IP地址,就像公司内部的分机号(比如分机号101、102)。这些地址在互联网上没有意义,也不能被路由。

范围:特意预留出了三段地址作为私有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 (小型网络,家庭网络最常见)

特点可以无限重复使用。你家可以用 192.168.1.1,我家也可以用 192.168.1.1,因为它们只在各自的内网中有效,互不冲突。

公有IP:

全球唯一的IP地址,就像电话号码的国家代码+区号+个人号码一样,不能重复。它是互联网上的“通用货币”,任何设备想要直接与互联网上的其他服务器(如谷歌、百度)通信,都必须有一个公有IP。

特点:由IANA、APNIC等国际或地区性互联网注册机构统一管理和分配。数量有限,需要付费租用。


而 NAT (网络地址转换)的核心功能是在将一个私有IP和端口号与为一个公有IP和端口号建立映射关系,这样一来,一个有限的公有IP就可以对应多个私有IP,在互联网上无数个私有IP的通信实际上就变成了有限的公有IP之间的通信,这样就基本解决了IP地址不够的问题。

NAT IP转换过程

当你的电脑想要访问百度:

第一步,内网请求:你的电脑(私有IP 192.168.1.101)想访问百度的服务器(公有IP 39.156.66.10)。它发送一个数据包:源地址: 192.168.1.101:54321目标地址: 39.156.66.10:80 

第二步,NAT转换:数据包先到达你的路由器。路由器会执行NAT操作:它用自己的公有IP替换掉数据包里的私有IP,并记录下这个转换关系。修改后的数据包:源地址: [你的公有IP]:62000 目标地址: 39.156.66.10:80 (百度)这个 62000 是路由器随机分配的一个端口号,用来唯一标识这是内网哪台设备发起的请求。

第三步,互联网路由:这个数据包在互联网上正常传输,最终到达百度。百度看来,这个请求就是来自 [你的公有IP]:62000,它会将回复发送到这个地址。

第四步,NAT转换:回复数据包回到了你的路由器:源地址: 39.156.66.10:80 目标地址: [你的公有IP]:62000 

第五步,转发回内网:路由器查看之前记录的转换表:将目标地址改回内部的私有IP。修改后的数据包:源地址: 39.156.66.10:80 目标地址: 192.168.1.101:54321,路由器将这个数据包准确发送给你的电脑。

整个过程对你的电脑和百度服务器都是透明的:你的电脑以为自己在直接和百度通信,百度也以为它是在和你的路由器通信。

NAPT

如果局域网内, 有多个主机都访问同一个公网服务器, 那么对于服务器返回的数据包,其目的IP都是相同的(路由器替换后的公有IP),那么路由器如何判定将这个数据包转发给哪个的主机?

这时候 NAPT 来解决这个问题了:使用 IP+port 来建立关联关系,即私有IP+端口号对应一个公有IP+端口号,同一局域网内,设备的私有IP被替换成的公有IP相同,但是被替换后的端口号不同,通过端口号就可以确定是哪个设备的哪个进程

路由

一跳

一跳指的是数据包在从源设备到目的设备的传输过程中,从一个网络节点转发到下一个直接相连的网络节点的一次移动。因为直接相连,所以它们之间通信使用的是MAC地址,而不是IP地址。要注意,一跳发生在数据链路层

而路由就是决定下一跳应该到跳哪一个IP地址下的过程,它发生在网络层。

路由的过程:一个数据包发给路由器,路由器查询路由表进行匹配:如果与目标主机直连则直接交付给对方;如果不行则尝试匹配路由表上的其他路由器,匹配则发给该路由器;如果都不匹配则发给默认路由器

到这里你可能会有一个疑惑:路由决定的不是下一跳的IP地址吗,而一跳用的是MAC地址啊,那它是怎么获取这个MAC地址的呢,这就需要ARP协议了

ARP协议

ARP协议的目的是通过IP地址获取相应的MAC地址

其过程分为两步:请求和应答

ARP请求(广播):

主机A首先查看自己的 ARP缓存表,看是否有该IP对应的MAC地址记录。

如果没有,主机A就会构造一个 ARP请求包。这个包的主要内容是:

发送方IP发送方MAC、目标IP目标MAC(全0,表示未知)

主机A将这个ARP请求包 以广播的形式发送到整个局域网。这意味着局域网内的所有设备都会收到这个包。

ARP应答(单播)

局域网内所有设备都会收到这个广播包,并拆开查看。

其他设备发现目标IP不是自己的,于是丢弃这个包。

主机B 发现目标IP正是自己的IP地址。主机B于是将主机A的IP和MAC地址对应关系记录到自己的ARP缓存表中。

随后向主机A发送一个ARP应答包(以单播的形式,直接发给电脑A的MAC地址)。这个包的内容是:发送方IP(主机B的IP)发送方MAC、(主机B的MAC)、目标IP、目标MAC

主机A收到主机B的ARP应答后,就知道了主机B的MAC地址。它将这个对应关系存入自己的 ARP缓存表 中,并设置一个有效期(通常几分钟到二十分钟)。现在,主机A就可以给主机B发送数据了。

IP协议

IP协议是用于将多个分组交换网络(数据报交换方式)连接起来的最典型通信协议。

该协议是无连接的服务,负责在源地址和目的地址之间传送数据报,然后为了适应不同网络对分组大小的要求,需要对上层传来的报文进行分割,最后调用本地网络协议将数据报传送给下一个网关或目的计算机。

1.主要功能

把数据报在互连的网络上传送,将数据报在一个个IP模块间传送直到传送到目的模块。网络中每个主机和网关上都有IP模块。数据报在一个个模块间通过路由处理网络地址传送到目的地址。

(1)寻址

在同一以太局域网内部,结点间的寻址可以通过二层MAC地址进行,但在不同网络之间,是不能通过MAC地址的,因为用于MAC地址寻址的广播帧只能在同一个以太网段内部进行

在不同网络中只能通过三层地址(该协议中为IP地址)进行寻址.

(2)数据报的封装

从传输层到达的数据段都需要经过IP协议进行重新封装的。因为IP协议是无连接的服务,并且采用数据报交换方式,所以封装后形成的是IP数据报。

IP封装的目的就是标识此IP数据报发送节点和接收节点的IP地址及控制信息

(3)分片与重组

不同网络上的链路可以传输的最大报文大小是不同的,这就是我们通常所说的MTU(最大传输单元)。为了使我们要传输的数据报能在不同网络中传输,当一些尺寸较大的数据报要在某个MTU值比较小的网络链路上传输时就可能需要对原来的数据报进行拆分,形成一个个小的分段,然后再把这些分段依次传输出去。

在接收节点自然就要把这些被拆分的分段重新组合起来,还原成原来的大的数据报的问题

下面我们来解释IP协议报头:

报头格式

4 位版本号(version):

指定 IP 协议的版本, 对于 IPv4 来说, 就是 4.

4 位头部长度(header length):

IP 头部的长度是4字节的多少倍, 4bit 表示最大的数字是 15, 因此 IP 头部最大长度是 60 字节.

8 位服务类型(Type Of Service),分别包括:3 位优先权字段(已经弃用), 4 位 TOS 字段, 和 1 位保留字段(必须置为 0).

4 位 TOS 分别表示: 最小延时, 最大吞吐量, 最高可靠性, 最小成本. 这四者相互冲突, 只能选择一个. 对于 ssh/telnet 这样的应用程序, 最小延 时比较重要; 对于 ftp 这样的程序, 最大吞吐量比较重要. 

16 位总长度(total length):

IP 数据报整体占多少个字节

16 位标识(id):

唯一的标识主机发送的报文. 如果 IP 报文在数据链路层被分片 了, 那么每一个片里面的这个 id 都是相同的.

3 位标志字段:

这个字段是分段标志,指出该IP数据报后面是否还有分段。目前只有前两位有意义:最低1位记为MF(More Fragment),如果MF=1,即表示后面还有分段,如果MF=0表示这已是某个数据报的最后一个分段;中间1位记为DF(Don’t Fragment),当DF=1时表示不允许分段,DF=0时表示允许分段;最高1位没有使用。

13 位分片偏移(framegament offset):

是分片相对于原始 IP 报文开始处的偏移. 其实就是在表示当前分片在原报文中处在哪个位置. 实际偏移的字节数是这个值乘8得到的. 因此, 除了最后一个报文之外, 其他报文的长度必须是 8 的整数倍(否则报文就不连续了).

8 位生存时间(Time To Live, TTL):

数据报到达目的地的最大报文跳数. 一般是 64. 每次经过一个路由, TTL -= 1, 一直减到 0 还没到达, 那么就丢弃了. 这个字段主要是用来防止出现报文在网络中循环路由

8 位协议:

表示上层协议的类型

16 位头部校验和: 使用 CRC 进行校验, 来鉴别头部是否损坏.

32 位源地址和 32 位目标地址: 表示发送端和接收端.

选项字段(不定长, 最多 40 字节): 略

分片与重组

想象一下,你要用一辆大卡车(大数据包)运送一批货物,但途中必须经过一条狭窄的隧道(MTU小的网络)。卡车无法直接通过,唯一的办法就是把货物卸下,分装到几辆小卡车(小数据包)上,依次通过隧道,到了宽阔的道路后再重新装回大卡车。

在网络中,这个“隧道的宽度限制”就是 MTU(Maximum Transmission Unit,最大传输单元)

定义:MTU是指数据链路层所能承载的上层数据(即IP数据包)的最大长度(单位:字节)。它是由底层的网络硬件和技术决定的。

常见的MTU值:

  • 以太网(Ethernet):MTU通常为 1500 字节(这是最常见的)。

  • PPPoE(宽带拨号连接):MTU通常为 1492 字节。

  • FDDI:MTU为4352字节。

  • 令牌环网:MTU可以是4464字节等。


当一个大的IP数据包从一个MTU较大的网络发出,要经过一个MTU较小的网络时,这个大数据包就无法被一次性传输。就要将这个数据包分成几个小段——分片,并在目的地进行还原——重组。

谁负责分片?谁负责重组?

分片:由路由器执行。当路由器收到一个IP数据包,其长度大于要将它转发出去的那个网络的MTU时,路由器就必须对这个数据包进行分片。

重组:由最终的目的主机执行。所有分片到达目的地后,由目的主机的IP层负责将它们重新组装成原始的数据包,再交给上层协议(如TCP/UDP)。中间的路由器绝不负责重组,它们只负责转发(可能包括分片)。

IP协议通过首部中的三个字段来协调分片和重组的过程:

16位分片标识

所有属于同一个原始IP包的分片,都拥有相同的标识符。这样,接收端才能知道哪些分片应该被组合在一起。

3位标志

位 0 (保留位):必须为0。

位 1 (DF - Don't Fragment,不分片)

如果设置为 1,则告诉途中的路由器:“禁止分片这个包”

如果路由器发现这个包太大又设置了DF位,它会直接丢弃该包,并向源主机发送一个ICMP“需要分片但DF位已设置”的错误消息。

位 2 (MF - More Fragments,更多分片)

如果设置为 1,表示这个分片不是最后一个,后面还有分片

如果设置为 0,表示这是原始包的最后一个分片,或者表示这个包本身就没被分片。

13位片偏移

作用:指示当前分片所携带的数据,在原始未分片IP包的数据部分中的起始位置(以8字节为单位)。这确保了接收端能够以正确的顺序重组分片,即使分片到达的顺序是乱序的。

如何进行重组?

目的主机收到分片后:

  1. 识别:根据标识符源IP地址,判断哪些分片属于同一个原始数据包。

  2. 排序:根据片偏移字段的值,对所有分片进行排序。

  3. 组装:检查第一个分片的偏移是否为0,最后一个分片的MF位是否为0。然后按顺序将每个分片的数据部分拼接起来。

  4. 交付:当所有分片都到达并组装完毕后,得到一个完整的原始IP数据包,计算其总长度,然后将其交付给上层协议(由IP首部的“协议”字段指定,如TCP或UDP)。

分片带来的问题

分片虽然解决了传输问题,但它是有代价的:

设想一下,一个大小为7420字节的数据包被分成了5个片段(每个片段刚好1480个字节),假设每个片段的丢包率为1%,那么一个片段都不丢失的几率为(99%)^5=95%,而如果丢失任何一个片段,整个IP数据包都无法重组,只能丢弃对于TCP而言这要重传整个数据包,而不是某一个丢失的片段,对比一下,分片传7420个字节的数据包,重传的期望为5%*7420B=371B,而如果一开始就在应用层控制数据包的大小,将其分为5个数据包,其重传的期望为5*1%*1500B=75B,因此还是应该尽量避免分片

http://www.xdnf.cn/news/18429.html

相关文章:

  • Spring Web MVC
  • 36v转5v峰值电流7A同步DC/DC降压芯片AH8655
  • C#开源库ACadSharp读取dwg图元的示例
  • Springboot项目的各层级详细总结
  • 【GaussDB】全密态等值查询功能测试及全密态技术介绍
  • Python socket远程部署工具服务
  • 论文阅读:Do As I Can, Not As I Say: Grounding Language in Robotic Affordances
  • 基于Django的学校实验室预约管理系统/基于python的实验室管理系统的设计与实现#python#django#FLASK
  • Spring Start Here 读书笔记:第9章 Using the Spring web scopes
  • Excel表格指定数据读取写入到另一个Excel表中(指定列指定行)
  • CXR-LT 2024:一场关于基于胸部X线的长尾、多标签和零样本疾病分类的MICCAI挑战赛|文献速递-深度学习人工智能医疗图像
  • 前端AI工具——TRAE
  • ExcelUtils实现 设置内容 插入行 复制行列格式
  • Blender模型动画导入到UE5
  • 【python】python进阶——推导式
  • 基于 SkyWalking + Elasticsearch + Grafana 的可落地调用链监控方案
  • 氙灯市场报告:亚太成增长主力,汽车、医疗、科研多领域需求驱动行业发展
  • 数据结构 -- 队列
  • Redis内存碎片深度解析:成因、检测与治理实战指南
  • Day16 二叉树part4
  • JDK21之虚拟线程的深入理解
  • Halcon那些事:什么是动态阈值,如何用dyn_threshold分割图片
  • 腾讯云COS SDK签名有效期设置为10分钟到期会自动刷新
  • Java后端学习路线
  • uniapp googlepay支付 内购项目
  • mysql编程(简单了解)
  • pthon实现bilibili缓存视频音频分离
  • 数据预处理学习笔记
  • 【C++】--函数参数传递:传值与传引用的深度解析
  • 防爆自动气象监测设备:高危环境的 “安全堡垒”