linux 进程间通信 dbus-glib【实例】详解二(上) 消息和消息总线(附代码)
linux 进程间通信 dbus-glib【实例】详解一(附代码)(d-feet工具使用)
linux 进程间通信 dbus-glib【实例】详解二(上) 消息和消息总线(附代码)
linux 进程间通信 dbus-glib【实例】详解二(下) 消息和消息总线(ListActivatableNames和服务器的自动启动)(附代码)
linux 进程间通信 dbus-glib【实例】详解三 数据类型和dteeth(类型签名type域)(层级结构:服务Service --> Node(对象、object) 等 )(附代码)
linux 进程间通信 dbus-glib【实例】详解四(上) C库 dbus-glib 使用(附代码)(编写接口描述文件.xml,dbus-binding-tool工具生成绑定文件)
linux 进程间通信 dbus-glib【实例】详解四(下) C库 dbus-glib 使用(附代码)
文章目录
- dbus实例讲解(二上):消息和消息总线
- 1、D-Bus的消息
- 1.1、消息类型
- 1.2、dbus-send和dbus-monitor
- 2、消息总线(dbus-daemon?)的方法和信号
- 2.1、概述
- 2.2、清单
- 2.3、练习
- 2.3.1、从ListName到d-feet的基本逻辑
dbus实例讲解(二上):消息和消息总线
应用程序A和消息总线连接,这个连接获取了一个众所周知的公共名(记作连接A)。应用程序A中有对象A1提供了接口I1,接口I1有方法M1。 应用程序B和消息总线连接,要求调用连接A上对象A1的接口I1的方法M1。
在上一讲的加法例子中,上面这段话可以实例化为:
应用程序example-service和会话总线连接。这个连接获取了一个众所周知的公共名“org.fmddlmyy.Test”。
应用程序example-servic中有对象“/TestObj”提供了接口“org.fmddlmyy.Test.Basic”,接口“org.fmddlmyy.Test.Basic”有方法“Add”。
应用程序d-feet和会话总线连接,要求调用连接“org.fmddlmyy.Test”上对象“/TestObj”的接口“org.fmddlmyy.Test.Basic”的方法“Add”。
应用程序B调用应用程序A的方法,其实就是应用程序B向应用程序A发送了一个类型为“method_call”的消息。 应用程序A通过一个类型为“method_return”的消息将返回值发给应用程序B。我们简单介绍一下D-Bus总线上的消息。
1、D-Bus的消息
上一讲说过最基本的D-Bus协议是一对一的通信协议。与直接使用socket不同,D-Bus是面向消息的协议。 D-Bus的所有功能都是通过在连接上流动的消息完成的。
1.1、消息类型
D-Bus有四种类型的消息:
- method_call 方法调用
- method_return 方法返回
- error 错误
- signal 信号
前面介绍的远程方法调用就用到了method_call和method_return消息。顾名思义,在发生错误时会产生error消息。 如果把method_call看作打电话,那么signal消息就是来电了。后面还会详细讨论。
1.2、dbus-send和dbus-monitor
dbus提供了两个小工具:dbus-send和dbus-monitor。我们可以用dbus-send发送消息。用dbus-monitor监视总线上流动的消息。 让我们通过dbus-send发送消息来调用前面的Add方法,这时dbus-send充当了应用程序B
。用dbus-monitor观察调用过程中的消息。
启动example-service:
$ ./example-service
在另一个控制台启动dbus-monitor:
$ dbus-monitor
dbus-monitor默认监视会话总线。执行:
$ dbus-send --session --type=method_call --print-reply --dest=org.fmddlmyy.Test /TestObj org.fmddlmyy.Test.Basic.Add int32:100 int32:999
输出为:
method return time=1642572373.469364 sender=:1.124 -> destination=:1.135 serial=118 reply_serial=2int32 1099
dbus-monitor的相关输出包括:
(我的ubuntu输出)
signal sender=org.freedesktop.DBus -> dest=(null destination) path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChangedstring ":1.22"string ""string ":1.22"
method call sender=:1.22 -> dest=org.freedesktop.DBus path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=Hello
method call sender=:1.22 -> dest=org.fmddlmyy.Test path=/TestObj; interface=org.fmddlmyy.Test.Basic; member=Addint32 100int32 999
method return sender=:1.21 -> dest=:1.22 reply_serial=2int32 1099
signal sender=org.freedesktop.DBus -> dest=(null destination) path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameOwnerChangedstring ":1.22"string ":1.22"string ""
:1.22就是dbus-send在本次调用中与会话总线所建立连接的唯一名。:1.21是连接“org.fmddlmyy.Test”的唯一名。 在以上输出中我们可以看到:1.22向“org.fmddlmyy.Test”发送method_call消息,调用Add方法。 :1.21通过method_return消息将调用结果发回:1.22。其它输出信息会在以后说明。
dbus-send的详细用法可以参阅手册。调用远程方法的一般形式是:
$ dbus-send [--system | --session] --type=method_call --print-reply --dest=连接名 对象路径 接口名.方法名 参数类型:参数值 参数类型:参数值
dbus-send支持的参数类型包括:string, int32, uint32, double, byte, boolean。
2、消息总线(dbus-daemon?)的方法和信号
2.1、概述
消息总线(dbus-daemon?)是一个特殊的应用,它可以在与它连接的应用之间传递消息。 可以把消息总线看作一台路由器。正是通过消息总线,D-Bus才在一对一的通信协议基础上实现了多对一和一对多的通信。
消息总线虽然有特殊的转发功能,但消息总线也还是一个应用。 其它应用与消息总线的通信也是通过1.1节的基本消息类型完成的。作为一个应用,消息总线也提供了自己的接口,包括方法和信号。
我们可以通过向连接“org.freedesktop.DBus ”上对象“/
”发送消息来调用消息总线提供的方法。 事实上,应用程序正是通过这些方法连接到消息总线上的其它应用,完成请求公共名等工作的。
2.2、清单
消息总线对象支持第一讲中提到的标准接口"org.freedesktop.DBus.Introspectable", 我们可以调用org.freedesktop.DBus.Introspectable.Introspect
方法查看消息总线对象支持的接口。例如:
$ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.Introspectable.Introspect
(arm摄像头上用:[root@RV1126_RV1109:~]# dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.Introspectable.Introspect
)
输出为:
(arm摄像头)
[root@RV1126_RV1109:~]# dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.Introspectable.Introspect
method return time=1642579767.439290 sender=org.freedesktop.DBus -> destination=:1.17 serial=3 reply_serial=2string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node><interface name="org.freedesktop.DBus"><method name="Hello"><arg direction="out" type="s"/></method><method name="RequestName"><arg direction="in" type="s"/><arg direction="in" type="u"/><arg direction="out" type="u"/></method><method name="ReleaseName"><arg direction="in" type="s"/><arg direction="out" type="u"/></method><method name="StartServiceByName"><arg direction="in" type="s"/><arg direction="in" type="u"/><arg direction="out" type="u"/></method><method name="UpdateActivationEnvironment"><arg direction="in" type="a{ss}"/></method><method name="NameHasOwner"><arg direction="in" type="s"/><arg direction="out" type="b"/></method><method name="ListNames"><arg direction="out" type="as"/></method><method name="ListActivatableNames"><arg direction="out" type="as"/></method><method name="AddMatch"><arg direction="in" type="s"/></method><method name="RemoveMatch"><arg direction="in" type="s"/></method><method name="GetNameOwner"><arg direction="in" type="s"/><arg direction="out" type="s"/></method><method name="ListQueuedOwners"><arg direction="in" type="s"/><arg direction="out" type="as"/></method><method name="GetConnectionUnixUser"><arg direction="in" type="s"/><arg direction="out" type="u"/></method><method name="GetConnectionUnixProcessID"><arg direction="in" type="s"/><arg direction="out" type="u"/></method><method name="GetAdtAuditSessionData"><arg direction="in" type="s"/><arg direction="out" type="ay"/></method><method name="GetConnectionSELinuxSecurityContext"><arg direction="in" type="s"/><arg direction="out" type="ay"/></method><method name="ReloadConfig"></method><method name="GetId"><arg direction="out" type="s"/></method><method name="GetConnectionCredentials"><arg direction="in" type="s"/><arg direction="out" type="a{sv}"/></method><property name="Features" type="as" access="read"><annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/></property><property name="Interfaces" type="as" access="read"><annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/></property><signal name="NameOwnerChanged"><arg type="s"/><arg type="s"/><arg type="s"/></signal><signal name="NameLost"><arg type="s"/></signal><signal name="NameAcquired"><arg type="s"/></signal></interface><interface name="org.freedesktop.DBus.Introspectable"><method name="Introspect"><arg direction="out" type="s"/></method></interface><interface name="org.freedesktop.DBus.Peer"><method name="GetMachineId"><arg direction="out" type="s"/></method><method name="Ping"></method></interface><node name="org/freedesktop/DBus"/>
</node>
"
[root@RV1126_RV1109:~]#
从输出可以看到会话总线对象支持标准接口“org.freedesktop.DBus.Introspectable”和接口“org.freedesktop.DBus”。 接口“org.freedesktop.DBus”有16个方法和3个信号。下表列出了“org.freedesktop.DBus”的12个方法的简要说明:
(这个表日后可能要做搜索用,附个链接:http://www.fmddlmyy.cn/mytext.html)
接口“org.freedesktop.DBus”的3个信号是:
2.3、练习
让我们来试试消息总线提供的方法。
2.3.1、从ListName到d-feet的基本逻辑
用dbus-send调用:
$ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames
(ubuntu里)
输出为:(略)
(arm摄像头里)
输出为:
[root@RV1126_RV1109:~]# dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames
method return time=1642596554.334145 sender=org.freedesktop.DBus -> destination=:1.13 serial=3 reply_serial=2array [string "org.freedesktop.DBus"string ":1.7"string ":1.8"string "rockchip.netserver"string "org.freedesktop.Avahi"string ":1.13"string ":1.0"string ":1.1"string ":1.2"string ":1.3"string "rockchip.system"string "net.connman"string ":1.4"string "fi.w1.wpa_supplicant1"string "rockchip.dbserver"string ":1.5"string "rockchip.StorageManager"string ":1.6"]
[root@RV1126_RV1109:~]#
这是会话总线当前已连接的连接名。在d-feet窗口的左侧窗口显示的就是ListNames返回的连接名。
(ubuntu d-feet软件)
聪明的读者也许已经想到使用消息总线的“org.freedesktop.DBus.ListNames”方法和各连接的“org.freedesktop.DBus.Introspectable.Introspect”, 我们就可以像d-feet一样查看总线上所有连接的所有对象的所有接口的所有方法和信号。
你的想法很好。但有一个问题,我们必须对连接中的对象调用“org.freedesktop.DBus.Introspectable.Introspect”方法。 ListNames只列出了连接名,我们怎么获取连接中的对象路径呢?
答案很简单,如果我们不知道对象路径就从根目录开始吧。连接中的对象是按照树型结构组织的。我们遍历连接的对象树就可以找到所有的对象。 调用对象的“org.freedesktop.DBus.Introspectable.Introspect”方法就可以查看对象的所有接口的所有方法和信号。
(如在arm摄像头里查看"rockchip.netserver"
所有方法)
[root@RV1126_RV1109:~]# dbus-send --system --type=method_call --print-reply --dest=rockchip.netserver / org.freedesktop.DBus.Introspectable.Introspect
method return time=1642598000.976271 sender=:1.4 -> destination=:1.15 serial=19 reply_serial=2string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node><interface name="org.freedesktop.DBus.Introspectable"><method name="Introspect"><arg name="xml" type="s" direction="out"/></method></interface><interface name="rockchip.netserver.server"><method name="GetService"><arg name="type" type="s" direction="in"/><arg name="json" type="s" direction="out"/></method><method name="GetNetworkIP"><arg name="type" type="s" direction="in"/><arg name="json" type="s" direction="out"/></method><method name="GetConfig"><arg name="service" type="s" direction="in"/><arg name="json" type="s" direction="out"/></method><method name="ScanWifi"></method><signal name="PowerChanged"><arg name="name" type="s"/><arg name="value" type="v"/></signal></interface>
<node name="net"/>
</node>"
[root@RV1126_RV1109:~]#
例如:假设我们不知道连接"org.fmddlmyy.Test"里有什么对象,我们可以对根对象"/"执行:
$ dbus-send --session --type=method_call --print-reply --dest=org.fmddlmyy.Test / org.freedesktop.DBus.Introspectable.Introspect
(当然,要先运行作者的example-service服务)
输出为:
[arnold@ubuntu ~/Arnold_test/20220119_test_dbus_demo4/hello-dbus3-0.1/src]1$ dbus-send --session --type=method_call --print-reply --dest=org.fmddlmyy.Test / org.freedesktop.DBus.Introspectable.Introspect
method return time=1642599939.774764 sender=:1.89 -> destination=:1.90 serial=8 reply_serial=2string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node><node name="TestObj"/>
</node>
"
[arnold@ubuntu ~/Arnold_test/20220119_test_dbus_demo4/hello-dbus3-0.1/src]2$
“org.fmddlmyy.Test"的对象树的根节点只有一个子节点"TestObj”,再查看"/TestObj":
$ dbus-send --session --type=method_call --print-reply --dest=org.fmddlmyy.Test /TestObj org.freedesktop.DBus.Introspectable.Introspect
[arnold@ubuntu ~/Arnold_test/20220119_test_dbus_demo4/hello-dbus3-0.1/src]2$ dbus-send --session --type=method_call --print-reply --dest=org.fmddlmyy.Test /TestObj org.freedesktop.DBus.Introspectable.Introspect
method return time=1642601175.664496 sender=:1.89 -> destination=:1.91 serial=9 reply_serial=2string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node><interface name="org.freedesktop.DBus.Introspectable"><method name="Introspect"><arg name="data" direction="out" type="s"/></method></interface><interface name="org.freedesktop.DBus.Properties"><method name="Get"><arg name="interface" direction="in" type="s"/><arg name="propname" direction="in" type="s"/><arg name="value" direction="out" type="v"/></method><method name="Set"><arg name="interface" direction="in" type="s"/><arg name="propname" direction="in" type="s"/><arg name="value" direction="in" type="v"/></method><method name="GetAll"><arg name="interface" direction="in" type="s"/><arg name="props" direction="out" type="a{sv}"/></method></interface><interface name="org.fmddlmyy.Test.Basic"><method name="Add"><arg name="arg0" type="i" direction="in"/><arg name="arg1" type="i" direction="in"/><arg name="ret" type="i" direction="out"/></method></interface>
</node>
"
[arnold@ubuntu ~/Arnold_test/20220119_test_dbus_demo4/hello-dbus3-0.1/src]3$
作为一个练习,让我们来查看系统总线的上的bluez接口。执行:(我发现我没bluez这个接口
linux 进程间通信 dbus-glib【实例】详解二(上) 消息和消息总线(附代码)相关推荐
- linux 进程间通信 dbus-glib【实例】详解二(下) 消息和消息总线(ListActivatableNames和服务器的自动启动)(附代码)
linux 进程间通信 dbus-glib[实例]详解一(附代码)(d-feet工具使用) linux 进程间通信 dbus-glib[实例]详解二(上) 消息和消息总线(附代码) linux 进程间 ...
- 详解pytorch实现猫狗识别98%附代码
详解pytorch实现猫狗识别98%附代码 前言 一.为什么选用pytorch这个框架? 二.实现效果 三.神经网络从头到尾 1.来源:仿照人为处理图片的流程,模拟人们的神经元处理信息的方式 2.总览 ...
- linux syslogd 源码,syslogd 详解二
相关博文: syslogd 详解一 syslogd 详解三 1. 前言 上一篇博文中详细了分析了syslogd的架构,解析了syslogd的调用过程,以及syslog.conf 的详细使用方法,这一篇 ...
- 太酷了!Linux的30 个实例详解 TOP 命令!
英文:Linoxide 编译:Linux中国/geekpilinux.cn/article-2352-1.html Linux中的top命令显示系统上正在运行的进程.它是系统管理员最重要的工具之一.被 ...
- LINUX操作系统的内核编译内幕详解二
5. Memory Technology Device(MTD) MTD设备支持.可不选. 6. Parallel port support 串口支持.如果不打算使用串口,就别选了. 7. Plug ...
- C#操作GridView控件绑定数据实例详解(二)
上文实现的GridView控件: (一)翻页功能 翻页内容,主要实现的是该控件下面,上下翻页,跳转到指定页面. 翻页功能要注意前台页面下面这段代码中的相关命令: <PagerTemplate & ...
- 朴素贝叶斯分类器详解及中文文本舆情分析(附代码实践)
参加 2018 AI开发者大会,请点击 ↑↑↑ 作者 | 杨秀璋(笔名:Eastmount),贵州财经大学信息学院老师,硕士毕业于北京理工大学,主要研究方向是Web数据挖掘.知识图谱.Python数据 ...
- 【C语言】初始C语言系列 代码详解 _ 编程入门 _【内附代码和图片】_ [初阶篇 _ 总结复习]
[前言] 本篇文章为初始C语言部分,C语言是编程的入门语言,所以也说是编程入门: 学好C语言的入门内容,才能真正的入门编程,而C语言的学习对于刚入门的同学还是有一些难度的,需要踏踏实实的自己去理解. ...
- linux 进程间通信 dbus-glib【实例】详解四(上) C库 dbus-glib 使用(附代码)(编写接口描述文件.xml,dbus-binding-tool工具生成绑定文件)(列集散集函数)
linux 进程间通信 dbus-glib[实例]详解一(附代码)(d-feet工具使用) linux 进程间通信 dbus-glib[实例]详解二(上) 消息和消息总线(附代码) linux 进程间 ...
最新文章
- 电子学会青少年编程等级考试案例:曲奇饼干
- 瞎忙不如不忙——读高德拉特《目标》有感
- as3 内容自适应容器大小
- php tiff,在PHP中将tiff转换为jpg?
- stack overflow at line
- iisnode默认不支持PUT和DELETE的解决
- params参数的调用
- 宽度为100%的HTML表格,在tbody中有垂直滚动
- 多元回归模型与热力图绘制
- iBase4J简单应用添加模块
- 数据结构1800题-错题集-第七章
- 腾讯云服务器SSH密匙登录教程(创建密匙/关联/登录)
- juniper防火墙软件升级
- 如何同步微信信息php,微信小程序中实现同步请求的方法
- The first GAN——Generative Adversarial Nets
- 第15.12节PyQt(Python+Qt)入门学习:可视化设计界面组件布局详解
- openvino杂烩
- HihoCoder上网络流算法题目建模总结
- Unity --- 摄像机的选择与设置
- 假设检验之z-检验,t-检验,卡方检验
热门文章
- java怎样开关语句随机数 不重复_怎样用java产生一个指定范围而且不重复的随机数?...
- python爬取音乐神器_Python爬虫提取神器,正则表达式(re模块),全程干货!
- ABAP delete的用法
- VL09增强-冲销校验
- 22、Power Query-文本字符的精确提取
- ABAP RANGES 在 RFC 的应用示例
- SAP中采购订单状态与MRP的关系
- 打车APP大数据宰客套路多:苹果比安卓贵、熟客比新客贵
- js输出一个菱形_Webpack 4入口、输出和ES6模块
- android 透明度变化,安卓获取屏幕的宽高并设置平移动画和透明度变化