Linux网络编程:网络层协议|IP

前言:

网络层协议解决什么问题

当我们在上层实现了应用层协议将字符流数据转化为结构体数据,在传输层完成了通信的实现,数据的传输,但是数据最终还是得从本主机输出,从网络中进入到远端的另外一台主机。

  • 网络层协议IP解决的就是两台主机间数据的转移,也就是提供了一种将数据包从一台主机送到一台主机的能力。 
  • 传输层协议TCP/UDP解决的是网络传输的可靠性,将数据传输到相应的应用程序
  • 应用层协议HTTP/HTTPS解决的是将字节流数据转化为结构体数据

如图:主机B发送数据包经由若干个路由器最终到达主机C 


基本概念

  • 主机: 配有IP地址, 但是不进行路由控制的设备;
  • 路由器: 即配有IP地址, 又能进行路由控制;
  • 节点: 主机和路由器的统称
  • 路由控制是路由器根据路由控制表转发数据包的过程。

1.IP协议 

1.1.IP协议格式


32位源IP和目的IP

 表示发送端的ip地址,和数据报文的目的主机地址。


4位版本

对应着IP协议版本

  • IPV4(表示4个字节表示IP地址)
  • IPV6(16个字节表示地址)

4位首部长度

和TCP协议的4位首部长度一致,单位也是4字节,大小最大为40字节


8位协议

用来识别数据报文是TCP协议还是UDP协议,防止不同类型的协议之间进行通信


16位总长度

表示整个报文的长度,并且已知报头长度固定为20字节,那么通过报文长度 = 报头长度 + 有效载荷长度,即可分离报文和报头


8位服务类型

用于数据包发送质量、效果优先级的选择。

  • 3位优先权字段(已经弃用),4位TOS字段,和1位保留字段(必须置为0)。
  • 4位TOS分别表示:最小延时,最大吞吐量,最高可靠性,最小成本。
  • 这四者相互冲突,只能选择一个。对于ssh/telnet这样的应用程序,最小延时比较重要; 对于ftp这样的程序, 最大吞吐量比较重要。

8位生存时间(TTL)

报文在路径转发过程中,经由路由器的跳数上限(不允许报文在路径节点进行无意义的节点转换,造成资源的浪费)


16位标识、3位标志、13位片偏移

因为在网络层的下一层数据链路层,最大允许发出报文长度为MTU=1500,也就是网络层形成报文之后可能大小会大于MTU,这时候就需要进行分片、多次发送。

  • 16位标识(id):唯一的标识主机发送的报文。如果IP报文在数据链路层被分片了,那么每一个片里面的这个id都是相同的(用来区分不同的报文)
  • 3位标志字段:第一位保留(默认填0,暂时没有意义)。第二位置为1表示禁止分片,这时候如果报文长度超过MTU,IP模块就会丢弃报文。 第三位表示"更多分片", 如果分片了的话,最后一个分片置为1,其他是0。类似于一个结束标记.
  • 13位分片偏移:是分片相对于原始IP报文开始处的偏移。其实就是在表示当前分片在原报文中处在哪个位置。实际偏移的字节数是这个值 * 8 得到的。因此,除了最后一个报文之外,其他报文的长度必须是8的整数倍(否则报文就不连续了)

1.2.网段划分

1.2.1.知识引入

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

  • 网络号: 保证相互连接的两个网段具有不同的标识;
  • 主机号: 同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号;

例如本机ip地址为127.0.0.1,其中127.0.0.为网络号,1为主机号

如图: 路由器连接了两个局域网,而在同一个局域网,我们发现网络号是相同的,不同的是主机号,所以我们就能够通过IP地址定位到网络号和主机号,进而找到唯一的主机!!!

路由器的作用:

  • 连接不同的网络
  • 构建子网
  • 进行数据包的路由和转发 

 1.2.2.IP地址划分和子网掩码

IP地址划分

在1.2.1.中我们知道IP地址划分成了网络号和主机号,保证在互相连接的网络中每一台主机的ip地址都不同,那么这时就会出现一个问题:网络号和主机号怎么设计,IP地址如何进行划分?

如图所示,为过去的一种IP地址划分的方案,为了应对不同的场景下(对应局域网的主机数量)的网络方案。

随着Internet的飞速发展,这种划分方案的局限性很快显现出来,大多数组织都申请B类网络地址,导致B类地址很快就分配完了,而A类却浪费了大量地址;

  • 例如,申请了一个B类地址,理论上一个子网内能允许6万5千多个主机。A类地址的子网内的主机数更多。
  • 然而实际网络架设中,不会存在一个子网内有这么多主句的情况。因此大量的IP地址都被浪费掉了。

我们也可以从网络的拓扑结构(两层)看出来,上述方案的IP地址利用率较低。

因此这样的固定长度划分方案,漏洞过大,并且当前国际上主流的IP地址版本为IPV4,即用4个字节(32位)来表示全球上的所有主机,理论上最多表示42亿台主机,所以IP地址也是一种资源,那么我们就需要采取其他方案在实现IP划分的同时,又保证IP地址利用率。 


子网掩码

针对这种情况提出了新的划分方案,称为CIDR(Classless Interdomain Routing):

  • 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号;
  • 子网掩码也是一个32位的正整数。通常用一串 "0" 来结尾;
  • 将IP地址和子网掩码进行 "按位与" 操作,得到的结果就是网络号;
  • 网络号和主机号的划分与这个IP地址是A类、B类还是C类无关;

 值得一提的是:子网掩码以一串“1”开头,以一串“0”结尾。

 如图:添加了子网掩码这个模块后,我们发现同一个IP地址转化后表示的子网内的地址范围存在不同,那为什么会导致这种不同呢?接下来我们通过下图来理解一下:

 看到这里大家可能理解了子网掩码的作用,但是应该没有理解到它的魅力,那我们通过A类方案的子网掩码化来体会一下(实际上A类方案不进行子网构建,一般为B为方案):

 对比原先的IP地址划分方案,我们发现网络拓扑:

  • 原先的IP地址划分结构为:大网络->主机
  • 添加子网掩码后:大网络->小网络->主机

所以我们实现了将没有利用到的主机号,转化成了“子网的网络号”,进而提升了IP地址的利用率。 

1.3.IP地址分类

1.3.1.特殊IP地址 

  • 将IP地址中的主机地址全部设为0,就成为了网络号,代表这个局域网
  • 将IP地址中的主机地址全部设为1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包
  • 127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1

 

1.3.2.私有IP和公网IP

如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到Internet上,理论上使用任意的IP地址都可以,但是RFC 1918规定了用于组建局域网的私有IP地址的规则:

  • 10.*,前8位是网络号,共16,777,216个地址
  • 172.16.到172.31.,前12位是网络号,共1,048,576个地址
  • 192.168.*,前16位是网络号,共65,536个地址

包含在这个范围中的,都称为私有IP(内网ip),其余的则称为全局IP(或公网IP)

我们的计算机是接入到运营商供给的私有网络的,而我们平时使用的云服务器就是公网IP。

如图:我们分层将广域网分为若干子网,然后子网接着划分为下一级子网,最终在连接上使用私有IP的主机,最终实现从广域网到局域网,从公有ip到私有ip。将子网划分提高了定位和查找主机的效率。 

  •  一个路由器可以配置两个IP地址,一个是WAN口IP,一个是LAN口IP(子网IP)
  • 路由器LAN口连接的主机,都从属于当前这个路由器的子网中
  • 不同的路由器,子网IP其实都是一样的(通常都是192.168.1.1),子网内的主机IP地址不能重复。但是子网之间的IP地址就可以重复了(只要WAN口IP不同即可区分)
  • 每一个家用路由器,其实又作为运营商路由器的子网中的一个节点。这样的运营商路由器可能会有很多级,最外层的运营商路由器,WAN口IP就是一个公网IP了。

1.3.3.NAT技术 

子网内的主机需要和外网进行通信时,路由器将IP首部中的IP地址进行替换(替换成WAN口IP),这样逐级替换,最终数据包中的IP地址成为一个公网IP。这种技术称为NAT (Network Address Translation,网络地址转换).

那么我们实际上进行网络通信时,数据报文在网络中是如何传送到服务器的呢?

首先内网IP不会出现在公网通信中,所以内网如果需要实现通信,就得一层一层通过路由器向上转发到运营商路由器中公网ip发送。并且向上转发时,需要将源IP替换成路由器的WAN口IP!!!这又是为什么呢?

因为路由器对应的子网IP不是表示当前路由器的标识,而是当前路由器的下一层子网的标识,而WAN口IP才是路由器网络中区分唯一路由器的标识!!!

这时我们就可以理解了NAT技术:逐级将当前的IP地址替换为当前对应的WAN口IP,直到转换为公网IP,也就是最上层的运营商路由器的WAN口IP。

1.4.路由

1.4.1.什么是路由

我们知道数据报文离开发送端后,并不是直接发送到接收端主机的,需要不断的通过中间节点(路由器)转发,不断路由直到到达接收端

  • 路由的过程,就是这样一跳一跳 “问路” 的过程。
  • “一跳”就是数据链路层中的一个区间。具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间

在智能手机未普及的时代,人们去一个很远的地方,是需要进行不断的问路,一步一步的从一个终点走到一个新的起点,再继续问路,直到最后走到目的地。

IP数据包的传输过程也和问路一样:

  1. 当IP数据包,到达路由器时,路由器会先查看目的IP
  2. 路由器决定这个数据包是能直接发送给目标主机,还是需要发送给下一个路由器
  3. 依次反复,一直到达目标IP地址

1.4.2.路由表

既然在网络中,数据报文是通过路由器在主机之间进行转发的,那么就会出现一个问题:数据报文怎么知道自己要去往哪一个路由器进行路由转发呢?这时IP协议就规定了每一个路由器节点中必须维护一张路由表,当数据报文到达一个节点时,通过查询路由表来获取下一个路由器的IP地址。

如图:为某一个路由器主机的路由表。

  • Destination:目的地址
  • Gateway:下一条地址
  • Genmask:子网掩码
  • Use Iface:发送接口

数据报文在路由器转发的过程: 

 数据报文在网络中转发的过程本质是:通过不同主机的路由表,和子网掩码按位与接着从相应地址的接口传到下一个主机,再继续这个循环

我们可以借助:route命令来查看当前主机的路由表

1.5.网络层数据切片和组装

我们在1.1.中提及:16位标识、3位标志、13位片偏移这三个字段,并且我们提及了MTU,即Maximum Transmission Unit,最大传输单元,它是计算机网络中用于描述数据帧的最大长度的一个参数。所以数据切片是为了解决数据帧过大的问题!!!

那么网络通信的过程中是如何实现数据的切片和组装的呢?

切片规则:

  • IP数据报文总大小为1500字节(包括20字节的固定报头)
  • 当数据报文超过1500字节时,切片的第一片3位标志为001,并且13位片偏移量为0
  • 切片的最后一片的3位标志为0,并且13位偏移量等于其他

如图:我们首先进行切片,因为MTU=1500,所以我们需要切成三片,接着将这三片数据传入数据链路层,最终发送到对端主机

而当我们在对端主机接收到许多数据帧,然后将帧头去掉后传到网络层后,我们如何找到这些切片后的数据报文,并把他们组装到一起?

组装规则:

  • 必须按照顺序、并且组装完整成分片前的完整的IP数据报文
  • 第一个切片的3位标志位001,并且13位偏移量为0
  • 根据相同的16位标识来对分片的报文进行组装

通过图上这种方式,我们就可以分别找到若干个段切片后的IP报文,接着我们保留第一个切片的报头,把其他切片报头除去,按照顺序将切片的所有IP报文恢复成切片前的完整的IP报文,传到传输层中。这就是数据的组装。


从传输层数据大小设置来替代数据切片

然而我们不得不承认:切片并不是一个好的传输策略,首先切成若干份,可能会增加丢包的风险,这时就会导致数据的传输需要消耗更加多的资源,那么我们如何解决这个问题呢?

我们知道IP报文需要进行切片的根本原因就是:

  • 数据链路层存在最大传输单元MTU

即IP层向下转发的数据报文过大,也可以说是传输层的TCP/UDP报文过大,那么我们就认为规定单次向网络层传输的字节数不超过 MSS = MTU - IP协议报头大小 - 以太网数据报头大小

这样我们就尽量避免了数据的切片和组装,但是实际应用上我们还是运行这种情况的出现……

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

瘦”AP与“胖”AP的区别

1. AP基本概念 无线AP,简单说就是一个无线接入点,它是无线网络的关键部分,就像是无线网络的大脑。这个无线AP啊,它跟无线路由器、无线网关、无线网桥这些设备差不多,都是干一件事儿的。它的作用就是把家里或公司里用线…

Redis 异常三连环

本文针对一种特殊情况下的Reids连环异常,分别是下面三种异常: NullPointerException: Cannot read the array length because “arg” is nullJedisDataException: ERR Protocol error: invalid bulk lengthJedisConnectionException: Unexpected end o…

续航1977公里的穿越之旅:比亚迪秦L DM-i试驾体验

5月31日,在西安这座古老而又充满活力的城市,一群自媒体驾驶着比亚迪秦L DM-i,踏上了从祖国西北到东南的穿越之旅。 在本次试驾活动中,自媒体们不仅要体验这款新能源车型的驾驶性能,而且还要亲自验证它在实际道路和极端…

基于聚类和回归分析方法探究蓝莓产量影响因素与预测模型研究

🌟欢迎来到 我的博客 —— 探索技术的无限可能! 🌟博客的简介(文章目录) 目录 背景数据说明数据来源思考 正文数据预处理数据读取数据预览数据处理 相关性分析聚类分析数据处理确定聚类数建立k均值聚类模型 多元线性回…

【专利 超音速】基于分类模型的轻量级工业图像关键点检测方法

申请号CN202311601629.7公开号(公开)CN117710683A申请日2023.11.27申请人(公开)超音速人工智能科技股份有限公司发明人(公开)张俊峰(总); 杨培文(总); 沈俊羽; 张小村 摘要 本发明涉及一种基于分类模型的…

【Makefile笔记】小白入门篇

【Makefile笔记】小白入门篇 文章目录 【Makefile笔记】小白入门篇所需组件一、简单了解Makefile1.Makefile简介2.Makefile 原理 二、为什么要使用Makefile1.解决编译时链库的不便2.提高编译效率,缩短编译时间(尤其是大工程) 三、Makefile语法…

vue 使用 Vxe UI vxe-print 实现复杂的 Web 打印,支持页眉、页尾、分页的自定义模板

Vxe UI vue 使用 Vxe UI vxe-print 实现复杂的 Web 打印,支持页眉、页尾、分页的自定义模板 官方文档 https://vxeui.com 查看 github、gitee 页眉-自定义标题 说明:vxe-print-page-break标签用于定义分页,一个标签一页内容,超…

Rust 性能分析

都说Rust性能好,但是也得代码写得好,猜猜下面两个代码哪个快 . - 力扣&#xff08;LeetCode&#xff09; use std::collections::HashMap; use lazy_static::lazy_static;lazy_static! {static ref DIGIT: HashMap<char, usize> {let mut m HashMap::new();for c in …

最新版点微同城源码34.7+全套插件+小程序前后端

带全套插件 自己耐心点配置一下插件 可以H5可以小程序 一款专属的同城服务平台对于企业和个人而言&#xff0c;无疑是拓展业务、提升服务品质的重要一环。点微同城源码搭配全套插件&#xff0c;以及完善的小程序前后端&#xff0c;将为您的业务发展提供强大支持 源码免费下载…

【PB案例学习笔记】-15怎样限制应用程序运行次数?

写在前面 这是PB案例学习笔记系列文章的第15篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gite…

python词云生成库-wordcloud

内容目录 一、模块介绍二、WordCloud常用的方法1. generate(self, text)2. generate_from_frequencies(frequencies)3. fit_words(frequencies)4. generate_from_text(text) 三、进阶技巧1. 设置蒙版2. 设置过滤词 WordCloud 是一个用于生成词云的 Python 库&#xff0c;它可以…

【算法速查】万字图解带你快速入门八大排序(下)

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;首先在这里祝大家中秋国庆双节同乐&#xff01;&#xff01;抓住假期的小尾巴&#xff0c;今天来把算法速查的八大排序的后续写完&#xff0c;当…

用 OpenCV 实现图像中水平线检测与校正

前言 在本文中&#xff0c;我们将探讨如何使用 Python 和 OpenCV 库来检测图像中的水平线&#xff0c;并对图像进行旋转校正以使这些线条水平。这种技术可广泛应用于文档扫描、建筑摄影校正以及机器视觉中的各种场景。 环境准备 首先&#xff0c;确保您的环境中安装了 OpenC…

gulimall-search P125 springboot整合elasticsearch版本冲突

一、问题 spring-boot.version 2.2.4.RELEASE,在gulimall-search pom.xml中添加elasticsearch.version 7.4.2后&#xff0c;发现出现如下问题&#xff1a;elasticsearch版本是springboot引入的6.8.6&#xff0c;没有变为7.4.2。 二、原因 在gulimall-search 的pom文件中&#…

01_初识微服务

文章目录 一、微服务概述1.1 什么是微服务1.2 对比微服务架构与单体架构1.3 微服务设计原则1.4 微服务开发框架1.5 简单理解分布式部署与集群部署 二、微服务的核心概念2.1 服务注册与发现2.2 微服调用&#xff08;通信&#xff09;2.3 服务网关2.4 服务容错2.5 链路追踪参考链…

初级网络工程师之入门到入狱(一)

本文是我在学习过程中记录学习的点点滴滴&#xff0c;目的是为了学完之后巩固一下顺便也和大家分享一下&#xff0c;日后忘记了也可以方便快速的复习。 网络工程师从入门到入狱 前言一、交换机二、路由器三、DHCP&#xff08;动态主机配置协议&#xff09;四、路由器配置 DHCP自…

前端面试宝典总结2-CSS(1)

前端面试宝典总结之CSS&#xff08;1&#xff09; 本文章 对各大学习技术论坛知识点&#xff0c;进行总结、归纳自用学习&#xff0c;共勉&#x1f64f; 上一篇&#x1f449;: 前端面试宝典总结1- html 文章目录 前端面试宝典总结之CSS&#xff08;1&#xff09;1.分析比较 o…

C++ | Leetcode C++题解之第129题求根节点到叶节点数字之和

题目&#xff1a; 题解&#xff1a; class Solution { public:int sumNumbers(TreeNode* root) {if (root nullptr) {return 0;}int sum 0;queue<TreeNode*> nodeQueue;queue<int> numQueue;nodeQueue.push(root);numQueue.push(root->val);while (!nodeQueu…

【全开源】CMS内容管理系统(ThinkPHP+FastAdmin)

基于ThinkPHPFastAdmin的CMS内容管理系统&#xff0c;自定义内容模型、自定义单页、自定义表单、专题、统计报表、会员发布等 提供全部前后台无加密源代码和数据库私有化部署&#xff0c;UniAPP版本提供全部无加密UniAPP源码​ &#x1f50d; 解锁内容管理新境界&#xff1a;C…

高级 Go 程序设计:使用 net/http/httputil 包构建高效网络服务

高级 Go 程序设计&#xff1a;使用 net/http/httputil 包构建高效网络服务 介绍ReverseProxy 的使用基本概念实现步骤高级配置实际案例 DumpRequest 的使用功能说明代码示例应用场景NewSingleHostReverseProxy 的特性功能概述 详细教程 注意事项使用 NewChunkedWriter 实现高效…