【ROS】—— ROS重名问题(九)

news2024/11/20 15:23:24

文章目录

  • 前言
  • 1. ROS工作空间覆盖
  • 2. ROS节点名称重名
    • 2.1 rosrun设置命名空间与重映射
      • 2.1.1 rosrun设置命名空间
      • 2.1.2 rosrun名称重映射
      • 2.1.3 rosrun命名空间与名称重映射叠加
    • 2.2 launch文件设置命名空间与重映射
    • 2.3 编码设置命名空间与重映射
      • 2.3.1 重映射
      • 2.3.2 C++ 实现:命名空间
  • 3. ROS话题名称设置
    • 3.1 rosrun设置话题重映射
    • 3.2 launch文件设置话题重映射
    • 3.3 编码设置话题名称
      • 3.3.1 C++实现
      • 3.3.2 python实现
  • 4. ROS参数名称设置
    • 4.1 rosrun设置参数
    • 4.2 launch文件设置参数
    • 4.3 编码设置参数
      • 4.3.1 C++
      • 4.3.2 python

前言

📢本系列将依托赵虚左老师的ROS课程,写下自己的一些心得与笔记。
📢课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ
📢讲义链接:http://www.autolabor.com.cn/book/ROSTutorials/index.html
📢 文章可能存在疏漏的地方,恳请大家指出。

1. ROS工作空间覆盖

所谓工作空间覆盖,是指不同工作空间中,存在重名的功能包的情形。

ROS 开发中,会自定义工作空间且自定义工作空间可以同时存在多个,可能会出现一种情况:虽然特定工作空间内的功能包不能重名,但是自定义工作空间的功能包与内置的功能包可以重名或者不同的自定义的工作空间中也可以出现重名的功能包,那么调用该名称功能包时,会调用哪一个呢?比如:自定义工作空间A存在功能包 turtlesim,自定义工作空间B也存在功能包turtlesim,当然系统内置空间也存在turtlesim,如果调用turtlesim包,会调用哪个工作空间中的呢?

一个例子:
1.新建工作空间A与工作空间B,两个工作空间中都创建功能包: turtlesim。
2.在 ~/.bashrc 文件下追加当前工作空间的 bash 格式如下:

source /home/用户/路径/工作空间A/devel/setup.bash
source /home/用户/路径/工作空间B/devel/setup.bash

3.新开命令行:source .bashrc加载环境变量
4.查看ROS环境环境变量echo $ROS_PACKAGE_PATH
结果:自定义工作空间B:自定义空间A:系统内置空间
5.调用命令:roscd turtlesim会进入自定义工作空间B

原因

ROS 会解析 .bashrc 文件,并生成 ROS_PACKAGE_PATH ROS包路径,该变量中按照 .bashrc 中配置设置工作空间优先级,在设置时需要遵循一定的原则:ROS_PACKAGE_PATH 中的值,和 .bashrc 的配置顺序相反—>后配置的优先级更高,如果更改自定义空间A与自定义空间B的source顺序,那么调用时,将进入工作空间A。

优先级顺序也可以用下列命令查看:

echo $ROS_PACKAGE_PATH

隐患
存在安全隐患,比如当前工作空间B优先级更高,意味着当程序调用 turtlesim 时,不会调用工作空间A也不会调用系统内置的 turtlesim,如果工作空间A在实现时有其他功能包依赖于自身的 turtlesim,而按照ROS工作空间覆盖的涉及原则,那么实际执行时将会调用工作空间B的turtlesim,从而导致执行异常,出现安全隐患。

BUG 说明:
当在 .bashrc 文件中 source 多个工作空间后,可能出现的情况,在 ROS PACKAGE PATH 中只包含两个工作空间,可以删除自定义工作空间的 build 与 devel 目录,重新 catkin_make,然后重新载入 .bashrc 文件,问题解决。

ROS中没有对功能包重名的补救措施,所以避免重名是十分必要的,

2. ROS节点名称重名

对于ROS节点名称重名问题,ROS给出了两种解决策略: 使用命名空间或名称重映射.同时,实现两种策略有以下三种途径:

  • rosrun 命令
  • launch 文件
  • 编码实现

2.1 rosrun设置命名空间与重映射

当同时启动两个同名的节点时,会使第一个节点崩溃.

rosrun turtlesim turtlesim_node

以rosrun的途径, 有以下三种方式进行节点重命名:

  • rosrun设置命名空间
  • rosrun名称重映射
  • rosrun命名空间与名称重映射叠加

2.1.1 rosrun设置命名空间

设置命名空间:

rosrun turtlesim turtlesim_node __ns:=first
rosrun turtlesim turtlesim_node  __ns:=second

两个节点都成功启动,再用rosnode Iist进行查看:

/first/turtlesim
/rosout
/second/turtlesim

不同节点前有不同的前缀.

2.1.2 rosrun名称重映射

为节点起别名:

rosrun turtlesim turtlesim_node __name:=first
rosrun turtlesim turtlesim_node __name:=second

两个节点都成功启动,再用rosnode Iist进行查看:

/first
/rosout
/second

或者

 rosrun turtlesim turtlesim_node /turtlesim:=first
yuan@yuan-Legion-Y9000P-IAH7H:~$ rosnode list
/first
/rosout

不过第二种方式不适用于python文件

rosrun publisher demo07.py /publisher:=pub
yuan@yuan-Legion-Y9000P-IAH7H:~$ rosnode list
/rosout
/talker_person_p

2.1.3 rosrun命名空间与名称重映射叠加

rosrun turtlesim turtlesim_node __ns:=second __name:=nd
rosrun turtlesim turtlesim_node __ns:=first  __name:=st
/first/st
/rosout
/second/nd

ps:
使用环境变量也可以设置命名空间,启动节点前在终端键入如下命令:
export ROS_NAMESPACE=xxxx

yuan@yuan-Legion-Y9000P-IAH7H:~$ rosnode list 
/demo/turtlesim
/rosout

2.2 launch文件设置命名空间与重映射

介绍 launch 文件的使用语法时,在 node 标签中有两个属性: name 和 ns,二者分别是用于实现名称重映射与命名空间设置的。使用launch文件设置命名空间与名称重映射也比较简单。

launch文件示例如下

<launch>

    <node pkg="turtlesim" type="turtlesim_node" name="t1" />
    <node pkg="turtlesim" type="turtlesim_node" name="t2" />
    <node pkg="turtlesim" type="turtlesim_node" name="t1" ns="hello"/>

</launch>

在 node 标签中,name 属性是必须的,ns 可选。

rosnode list查看节点信息,显示结果:

/t1
/t2
/t1/hello

2.3 编码设置命名空间与重映射

如果自定义节点实现,那么可以更灵活的设置命名空间与重映射实现。

2.3.1 重映射

其实在之前的课程中,已经有过相关实践了,见【ROS】—— ROS通信机制进阶(七)中的初始化函数.这里再将其简单的罗列:

C++
核心代码:ros::init(argc,argv,"zhangsan",ros::init_options::AnonymousName);
python
核心代码:rospy.init_node("lisi",anonymous=True)

2.3.2 C++ 实现:命名空间

核心代码

  std::map<std::string, std::string> map;
  map["__ns"] = "xxxx";
  ros::init(map,"wangqiang");

3. ROS话题名称设置

在ROS中节点名称可能出现重名的情况,同理话题名称也可能重名。

在实际应用中,按照逻辑,有些时候可能需要将相同的话题名称设置为不同,也有可能将不同的话题名设置为相同。在ROS中给出的解决策略与节点名称重命类似,也是使用名称重映射或为名称添加前缀。根据前缀不同,有全局相对、和私有三种类型之分。

  • 全局(参数名称直接参考ROS系统,与节点命名空间平级)
  • 相对(参数名称参考的是节点的命名空间,与节点名称平级)
  • 私有(参数名称参考节点名称,是节点名称的子级)

3.1 rosrun设置话题重映射

启动乌龟节点

rosrun turtlesim turtlesim_node

启动键盘节点

rosrun teleop_twist_keyboard teleop_twist_keyboard.py

会出现以下结果

Waiting for subscriber to connect to /cmd_vel
Waiting for subscriber to connect to /cmd_vel
Waiting for subscriber to connect to /cmd_vel
Waiting for subscriber to connect to /cmd_vel
Waiting for subscriber to connect to /cmd_vel
Waiting for subscriber to connect to /cmd_vel
Waiting for subscriber to connect to /cmd_vel
Waiting for subscriber to connect to /cmd_vel
Waiting for subscriber to connect to /cmd_vel
Waiting for subscriber to connect to /cmd_vel
Waiting for subscriber to connect to /cmd_vel
Waiting for subscriber to connect to /cmd_vel

查看rostopic list

yuan@yuan-Legion-Y9000P-IAH7H:~$ rostopic list
/cmd_vel
/rosout
/rosout_agg
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

很明显,这是由于话题名称不一致导致的.对此,我们可以将turtlesim的/cmd_vel改为/turtle1/cmd_vel,或者将teleop_twist_keyboard 的/turtle1/cmd_vel改为/cmd_vel.

# 方案1
rosrun turtlesim turtlesim_node
rosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/turtle1/cmd_vel
#方案2
rosrun turtlesim turtlesim_node /turtle1/cmd_vel:=/cmd_vel
rosrun teleop_twist_keyboard teleop_twist_keyboard.py 

3.2 launch文件设置话题重映射

remap的应用在【ROS】—— ROS运行管理 ——元功能包与launch文件(八)中的remap函数中已经讲述过,这里再简单说明一下.

launch 文件设置话题重映射语法:

<node pkg="xxx" type="xxx" name="xxx">
    <remap from="原话题" to="新话题" />
</node>

实现teleop_twist_keyboard与乌龟显示节点通信方案有两种:

1.方案1
将 teleop_twist_keyboard 节点的话题设置为/turtle1/cmd_vel

<launch>

    <node pkg="turtlesim" type="turtlesim_node" name="t1" />
    <node pkg="teleop_twist_keyboard" type="teleop_twist_keyboard.py" name="key">
        <remap from="/cmd_vel" to="/turtle1/cmd_vel" />
    </node>

</launch>

2.方案2

将乌龟显示节点的话题设置为 /cmd_vel

<launch>
    <node pkg="turtlesim" type="turtlesim_node" name="t1">
        <remap from="/turtle1/cmd_vel" to="/cmd_vel" />
    </node>
    <node pkg="teleop_twist_keyboard" type="teleop_twist_keyboard.py" name="key" />

</launch>

3.3 编码设置话题名称

话题的名称与节点的命名空间、节点的名称是有一定关系的,话题名称大致可以分为三种类型(之间的关系可以参考下图):

  • 全局(参数名称直接参考ROS系统,与节点命名空间平级)
  • 相对(参数名称参考的是节点的命名空间,与节点名称平级)
  • 私有(参数名称参考节点名称,是节点名称的子级)
    在这里插入图片描述

3.3.1 C++实现

演示准备:

1.初始化节点设置一个节点名称

ros::init(argc,argv,"hello")

2.设置不同类型的话题
3.启动节点时,传递一个 __ns:= xxx
4.节点启动后,使用 rostopic 查看话题信息

全局
格式:以/开头的名称,和节点名称无关
示例1

 ros::Publisher pub= nh.advertise<std_msgs::String>("/chatter",1000);

结果

/chatter
/rosout
/rosout_agg

示例2

    ros::Publisher pub= nh.advertise<std_msgs::String>("/yuan/chatter",1000);

结果

/rosout
/rosout_agg
/yuan/chatter

相对
格式:非/开头的名称,参考命名空间(与节点名称平级)来确定话题名称
示例1

ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000);
xxx/chatter

示例2

ros::Publisher pub = nh.advertise<std_msgs::String>("chatter/money",1000);
xxx/chatter/money

私有名称
示例1

    ros::NodeHandle nh("~");
    ros::Publisher pub= nh.advertise<std_msgs::String>("chatter",1000);
/topic/xxx/chatter

示例2

ros::NodeHandle nh("~");
ros::Publisher pub= nh.advertise<std_msgs::String>("yuan/chatter",1000);
/topic/xxx/yuan/chatter

示例3
PS:当使用~,而话题名称有时/开头时,那么话题名称是绝对的

ros::NodeHandle nh("~");
ros::Publisher pub= nh.advertise<std_msgs::String>("/chatter",1000);
/chatter

3.3.2 python实现

全局名称
格式:以/开头的名称,和节点名称无关
比如:/xxx/yyy/zzz

示例1

ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter",1000);
/chatter

示例2:

ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter/money",1000);
/chatter/money

相对名称
格式:非/开头的名称,参考命名空间(与节点名称平级)来确定话题名称

示例1:

ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000);
/xxx/chatter

示例2:

ros::Publisher pub = nh.advertise<std_msgs::String>("chatter/money",1000);
/xxx/chatter/money

私有名称

格式:以~开头的名称

示例1:

ros::NodeHandle nh("~");
ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000);
/xxx/hello/chatter

示例2:

ros::NodeHandle nh("~");
ros::Publisher pub = nh.advertise<std_msgs::String>("chatter/money",1000);
/xxx/hello/chatter/money

4. ROS参数名称设置

在ROS中节点名称话题名称可能出现重名的情况,同理参数名称也可能重名。

关于参数重名的处理,没有重映射实现,为了尽量的避免参数重名,都是使用为参数名添加前缀的方式,实现类似于话题名称,有全局、相对、和私有三种类型之分。

  • 全局(参数名称直接参考ROS系统,与节点命名空间平级)
  • 相对(参数名称参考的是节点的命名空间,与节点名称平级)
  • 私有(参数名称参考节点名称,是节点名称的子级)

4.1 rosrun设置参数

rosrun 在启动节点时,也可以设置参数:
语法: rosrun 包名 节点名称 _参数名:=参数值

示例1

rosrun turtlesim turtlesim_node _A:=100

rosparam list查看节点信息,显示结果:
/turtlesim/A
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r

4.2 launch文件设置参数

该方式在【ROS】—— ROS运行管理 ——元功能包与launch文件(八)中的param中已经讲述过,这里再简单说明一下.

以 param 标签为例,设置参数

<launch>

    <param name="p1" value="100" />
    <node pkg="turtlesim" type="turtlesim_node" name="t1">
        <param name="p2" value="100" />
    </node>

</launch>

rosparam list查看节点信息,显示结果:
/p1
/t1/p1

4.3 编码设置参数

【ROS】—— ROS通信机制——参数服务器(四)也涉及了相关参数的知识.

4.3.1 C++

1. ros::param设置参数

#include "ros/ros.h"

int main(int argc, char *argv[])
{
    ros::init(argc,argv,"param_name");
    ros::NodeHandle nh;

    /*
        使用 ros::param 设置参数
    */
   //全局
    ros::param::set("/A",100);
   //相对
   ros::param::set("B",100);
   //私有
   ros::param::set("~C",100);
    return 0;
}

rosrun rename01 param_name  __ns:=param
/A
/param/B
/param/param_name/C

2. ros::NodeHandle设置参数

#include "ros/ros.h"

int main(int argc, char *argv[])
{
    ros::init(argc,argv,"param_name");
    ros::NodeHandle nh;

    /*
        使用 ros::param 设置参数
    */
   //全局
    ros::param::set("/A",100);
   //相对
   ros::param::set("B",100);
   //私有
   ros::param::set("~C",100);

       /*
        使用 ros::NodeHandle 设置参数
    */
    //全局
    nh.setParam("/D",1000);
    //相对
     nh.setParam("E",1000);
    //私有
    ros::NodeHandle nh_private("~");
     nh_private.setParam("F",1000);
    return 0;
}

rosrun rename01 param_name  __ns:=param
/A
/D
/param/B
/param/E
/param/F
/param/param_name/C
/param/param_name/F

4.3.2 python

python 中关于参数设置的语法实现比 C++ 简洁一些,调用的API时 rospy.set_param,该函数中,参数1传入参数名称,参数2是传入参数值,参数1中参数名称设置时,如果以 / 开头,那么就是全局参数,如果以 ~ 开头,那么就是私有参数,既不以 / 也不以 ~ 开头,那么就是相对参数。代码示例:

rospy.set_param("/py_A",100)  #全局,和命名空间以及节点名称无关
rospy.set_param("py_B",100)  #相对,参考命名空间
rospy.set_param("~py_C",100)  #私有,参考命名空间与节点名称

运行时,假设设置的 namespace 为 xxx,节点名称为 yyy,使用 rosparam list 查看:

/py_A
/xxx/py_B
/xxx/yyy/py_C

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

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

相关文章

Maven基础学习——依赖配置(1):配置同一项目下的三个工程

依赖配置一、前言二、创建第一个工程三、新建第二个工程四、创建第三个工程五、配置1.每个工程的.xml文件2.文件配置六、结语一、前言 在讲述依赖配置时&#xff0c;需要使用实例来说明&#xff0c;在B站黑马课程&#xff08;第12小节&#xff09;中没有讲到如何配置基础的三个…

[Effective Objective] 熟悉Objective-C

了解 Objective-C Objective_C 是一种面向对象的语言。但与jave、C等语言不同&#xff0c;它使用了消息结构&#xff08;messaging structure&#xff09;而非函数调用&#xff08;function calling&#xff09;。Objective-C由Smalltalk演化而来&#xff0c;后者是消息语言的…

React 学习笔记总结(六)

文章目录1. redux 介绍2. redux 工作流程3. redux 的使用4. redux 完整结构补充5. redux的 异步action6. react-redux库 与 redux库7. react-redux库的 实战8. react-redux的connect 最精简写法9. react-redux的 Provider组件作用10. react-redux 整合UI组件 和 容器组件11. re…

webgl图形平移、缩放、旋转

文章目录前言平移图示代码示例缩放图示代码示例旋转公式推导代码示例总结前言 在webgl中将图形进行平移、旋转、缩放的操作称为变换或仿射变换&#xff0c;图形的仿射变换涉及到顶点位置的修改&#xff0c;通过顶点着色器是比较直接的方式。本文通过着色器实现对webgl图形的仿…

ArcGIS基础实验操作100例--实验65按字段调整点符号方向

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a;请访问实验1&#xff08;传送门&#xff09; 高级编辑篇--实验65 按字段调整点符号方向 目录 一、实验背景 二、实验数据 三、实验步骤 &#xff0…

计算机组成原理_总线

计算机组成原理总目录总线概述 1. 总线介绍 我们知道计算机中有CPU、主存、辅存&#xff0c;以及打印机、键盘、鼠标等等的一些外设 那么各个设备之间肯定是要进行数据传输的&#xff0c;这就需要许多线路将它们连接起来 第一种方法&#xff1a;两两相联 外设数量越多&#xf…

35、基于STM32的电子钟(DS1302)

编号&#xff1a;35 基于STM32的电子钟&#xff08;DS1302&#xff09; 功能描述&#xff1a; 本设计由STM32单片机液晶1602按键DS1302时钟组成。 1、采用STM32F103最小系统。 2、利用DS1302芯片提供时钟信号 3、液晶1602实时显示年月日、时分秒、星期等信息。 4、三个按键可…

隐形AR眼镜厂商Mojo Vision裁员75%,专注Micro LED技术

1月7日青亭网报道&#xff0c;隐形AR眼镜厂商Mojo Vision官方宣布了一项重大调整&#xff0c;其中因为产品进展问题&#xff0c;同时还有融资进展受阻等面临大裁员&#xff0c;将进行一系列中心调整&#xff0c;据了解本次裁员比例高达75%。重点关注&#xff1a;1&#xff0c;M…

【Day5】力扣第328题,奇偶链表

前言&#xff1a; 大家好&#xff0c;我是良辰丫&#x1f680;&#x1f680;&#x1f680;&#xff0c;今天带大家刷一个力扣链表题&#xff0c;有人可能会说&#xff0c;一道题够嘛&#xff0c;刚开始刷题别着急&#xff0c;毕竟&#xff0c;心急吃不了热豆腐&#xff0c;&…

Mathorcup数学建模竞赛第六届-【妈妈杯】B题:小区车位分布的评价和优化模型(附特等奖获奖论文和Java代码)

赛题描述 随着现代社会经济的快速发展,房地产成为国家经济发展中重要的经济增长点之一。而小区内汽车停车位的分布对于小区居民的上下班出行影响很大。请建立数学模型,解决下列问题: 问题1:分析评判小区汽车停车位分布是否合理的几个关键指标,建立评判车位分布合理的数学…

嵌入式Linux-对子进程的监控

1. 进程的诞生与终止 1.1 进程的诞生 一个进程可以通过 fork()或 vfork()等系统调用创建一个子进程&#xff0c;一个新的进程就此诞生&#xff01;事实上&#xff0c;Linux系统下的所有进程都是由其父进程创建而来&#xff0c;譬如在 shell 终端通过命令的方式执行一个程序./…

leetcode 1658. 将 x 减到 0 的最小操作数[python3 双指针实现与思路整理]

题目 给你一个整数数组 nums 和一个整数 x 。每一次操作时&#xff0c;你应当移除数组 nums 最左边或最右边的元素&#xff0c;然后从 x 中减去该元素的值。请注意&#xff0c;需要 修改 数组以供接下来的操作使用。 如果可以将 x 恰好 减到 0 &#xff0c;返回 最小操作数 &a…

HTML与CSS基础(四)—— CSS基础(选择器进阶、Emmet语法、背景属性、元素显示模式、三大特性)

一、选择器进阶目标&#xff1a;能够理解 复合选择器 的规则&#xff0c;并使用 复合选择器 在 HTML 中选择元素1. 复合选择器1.1 后代选择器&#xff1a;空格作用&#xff1a;根据 HTML 标签的嵌套关系&#xff0c;选择父元素 后代中 满足条件的元素 选择器语法&#xff1a;选…

第二章JavaWeb基础学习路线

文章目录什么是Java WebJava Web基础的技术栈关于我们的客户端与服务端&#xff08;BS&#xff09;我们客户端的形式**PC端网页****移动端**服务端应用程序关于请求&#xff08;request&#xff09;和响应(response)类比生活中的请求和响应服务器中的请求和响应项目的逻辑构成架…

CSS权威指南(六)文字属性

1.缩进和行内对齐 &#xff08;1&#xff09;缩进文本&#xff08;text-indent&#xff09; text-indent属性把元素的第一行文本缩进指定的长度&#xff0c;缩进的长度可以可以是负值。这个属性通常用于缩进段落的第一行。text-indent作用于块级元素之上&#xff0c;缩进将沿着…

config:配置中心

Spring Cloud Config 为分布式系统中的外部配置提供服务器端和客户端支持。使用 Config Server&#xff0c;您可以集中管理所有环境中应用程序的外部配置。 Spring Cloud Config就是一个配置中心&#xff0c;所有的服务都可以从配置中心取出配置&#xff0c;而配置中心又可以从…

mmap(内存映射)、sendfile() 与零拷贝技术

内存映射&#xff08;Memory-mapped I/O&#xff09;是将磁盘文件的数据映射到内存&#xff0c;用户通过修改内存就能修改磁盘文件。 RocketMQ为什么快&#xff1f;kafka为什么快&#xff1f;什么是mmap&#xff1f;这些问题都逃不过一个点&#xff0c;就是零拷贝。 虽然还有其…

电脑不能开机的几个常见原因

现在手机已经将电脑取代了&#xff0c;用电脑的越来越少&#xff0c;因为一些原因上网课的多了起来&#xff0c;大家都将放置几年的电脑搬了出来&#xff0c;开不开机的大有人在&#xff0c;由于机器闲置很久大多都出现了各种各样的故障和问题&#xff0c;在这里总结了电脑台式…

C语言:浮点型存储方式

浮点型存储方式 任意一个二进制浮点数V可以表示成下面的形式 (-1)^S *M *2^E 1&#xff08;S符号位&#xff09; 8&#xff08;E阶码&#xff09; 23&#xff08;M尾码&#xff09;省略首位1 S&#xff1a;表示正负 只有0/1两个值 M&#xff1a;由浮点数转化成二进制数表示 在…

4.7、IPv4 数据报的首部格式

固定部分&#xff1a;每个 IP 数据报首部都必须包含的内容 某些 IP 数据报的首部除了包含 202020 字节的固定部分外&#xff0c;还包含一些可选的字段来增加 IP 数据报的功能 IP 数据报的首部常以 323232 个比特为单位进行描述 图中的每一行都由 323232 个比特&#xff08;也…