DBus 介绍

2023-11-09

一、什么是 DBus?

D-Bus是一个为应用程序间通信的消息总线系统, 用于进程之间的通信。

1.1 三层架构

1、函数库libdbus ------>>>>> 用于两个应用程序互相联系和交互消息。

2、基于 libdbus 构造的消息总线守护进程,可同时与多个应用程序相连,并能把来自一个应用程序的消息路由到0或者多个其他程序。

3、基于特定应用程序框架的封装库或捆绑(wrapper libraries or bindings )。

1.2 高层功能

  • 结构化的名字空间
  • 独立于架构的数据格式
  • 支持消息中的大部分通用数据元素
  • 带有异常处理的通用远程调用接口
  • 支持广播类型的通信

1.3 Bus daemon 总线守护

基于 libdbus 构造的消息总线守护进程,可同时与多个应用程序相连,并能把来自一个应用程序的消息路由到0或者多个其他程序。

从一个进程传递消息给另外一个进程,如果有很多 applications 链接到这个通道上,这个 daemon进程就会把消息转发给这些链接的所有程序。

DBus 是点对点通信,,经过 daemon 抽象后, 并由他寻址和发送消息,每个进程不关心消息发给哪个进程。

发送消息的过程:

第一步:创建和发送消息给后台 bus daemon 进程,这个过程中会有两个上下文的切换

第二步:bus daemon进程会处理该消息,并转发给目标进程,引起上下文的切换目标程序接收到消息。

传递大量的数据,D-Bus不建议,建议共享内存。

二、 介绍

2.1 通讯逻辑图

 

在通讯中分为三种角色,分别为:client、bus daemon 和 server。通讯的过程主要分 client 和 server :

  1. client 需先连接到总线(dbus_bus_get),其次构造消息(dbus_message_new_signal),然后发送消息(dbus_connection_send)到后台进程。后台进程接收消息,然后根据消息类型对消息进行不同处理(bus_dispatch_matches)。
  2. server 接收消息前需要连接到总线,并告知总线需要的消息类型(dbus_bus_add_match),然后等待接收消息(dbus_connection_pop_message)。server 收到总线转发的消息时会根据消息类型,做不同的处理。

2.2 使用案例

2.2.1 clent 发送数据

int main ()

{

GMainLoop *loop; // 定义一个事件循环对象的指针

DBusConnection *bus; // 定义总线连接对象的指针

DBusError error; // 定义D-Bus错误消息对象

loop = g_main_loop_new(NULL, FALSE); // 创建新事件循环对象

dbus_error_init (&error); // 将错误消息对象连接到D-Bus

// 错误消息对象

bus = dbus_bus_get(DBUS_BUS_SESSION, &error);// 连接到总线

if (!bus) {

g_warning("连接到D-Bus失败: %s", error.message); //判断是否连接错误

dbus_error_free(&error); //清除错误消息

return 1;

}

dbus_connection_setup_with_g_main(bus, NULL); // 将总线设为接收GLib事件循环

g_timeout_add(1000, (GSourceFunc)send_ding, bus);

// 每隔1000ms调用一次send_ding()函数

// 将总线指针作为参数

g_main_loop_run(loop); // 启动事件循环

return 0;

}

static gboolean send_ding(DBusConnection *bus) // 定义发送消息函数的细节

{

DBusMessage *message; // 创建消息对象指针

message = dbus_message_new_signal("/com/burtonini/dbus/ding",

"com.burtonini.dbus.Signal",

"ding"); // 创建消息对象并标识路径

dbus_message_append_args(message,

DBUS_TYPE_STRING, "ding!",

DBUS_TYPE_INVALID); //将字符串Ding!定义为消息

dbus_connection_send(bus, message, NULL); // 发送该消息

dbus_message_unref(message); // 释放消息对象

g_print("ding!\n"); // 该函数等同与标准输入输出

return TRUE;

}

2.2.2 server 接收数据

 

int main()

{

GMainLoop *loop; // 定义一个事件循环对象的指针

DBusConnection *bus; // 定义总线连接对象的指针

DBusError error; // 定义D-Bus错误消息对象

loop = g_main_loop_new(NULL, FALSE); // 创建新事件循环对象

dbus_error_init(&error); // 将错误消息对象连接到D-Bus

bus = dbus_bus_get(DBUS_BUS_SESSION, &error); // 连接到总线

if (!bus) { // 判断是否连接错误

g_warning("连接到D-Bus失败: %s", error.message);

dbus_error_free(&error); // 清除错误消息

return 1;

}

dbus_connection_setup_with_g_main(bus, NULL);// 将总线设为接收GLib事件循环

dbus_bus_add_match(bus, "type='signal',interface

='com.burtonini.dbus.Signal'"); // 定义匹配器

dbus_connection_add_filter(bus, signal_filter, loop, NULL); // 调用函数接收消息

g_main_loop_run(loop); // 启动事件循环

return 0;

}

// 定义接收消息函数的细节

static DBusHandlerResult signal_filter(DBusConnection *connection, DBusMessage *message, void *user_data)

{

GMainLoop *loop = user_data; // 定义事件循环对象的指针,并与主函数中的同步

if (dbus_message_is_signal(message, DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,

"Disconnected")) // 接收连接成功消息,判断是否连接失败

{

g_main_loop_quit (loop); // 退出主循环

return DBUS_HANDLER_RESULT_HANDLED;

}

// 指定消息对象路径,判断是否成功

if (dbus_message_is_signal(message, "com.burtonini.dbus.Signal",

"Ping"))

{

DBusError error; // 定义错误对象

char *s;

dbus_error_init(&error); // 将错误消息对象连接到D-Bus错误

if (dbus_message_get_args(message, &error, DBUS_TYPE_STRING, &s,

DBUS_TYPE_INVALID)) // 接收消息,并判断是否有错误

{

g_print("接收到的消息是: %s\n", s); // 输出接收到的消息

dbus_free (s); // 清除该消息

}

else

{

// 有错误时执行下列语句

g_print("消息已收到,但有错误提示: %s\n", error.message);

dbus_error_free (&error);

}

return DBUS_HANDLER_RESULT_HANDLED;

}

return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;

}

API

void dbus_error_init(DBusError *error);

目的:

参数:

[in]

[out]

过程:

DBusConnection *dbus_bus_get(DBusBusType type, DBusError *error);

目的:

参数:

[in]

[out]

过程:

void dbus_connection_setup_with_g_main (DBusConnection *connection,

GMainContext *context);

目的:

参数:

[in]

[out]

过程:

void dbus_bus_add_match(DBusConnection *connection,

const char *rule,

DBusError *error);

目的:

参数:

[in]

[out]

过程:

dbus_bool_t dbus_connection_add_filter(DBusConnection *connection,

DBusHandleMessageFunction function,

void *user_data,

DBusFreeFunction free_data_function);

目的:

参数:

[in]

[out]

过程:

dbus_bool_t dbus_message_is_signal(DBusMessage *message,

const char *interface,

const char *signal_name);

目的:

参数:

[in]

[out]

过程:

dbus_bool_t dbus_message_get_args(DBusMessage *message,

DBusError *error,

int first_arg_type,

...);

目的:

参数:

[in]

[out]

过程:

DBusMessage* dbus_message_new_signal(const char *path,

const char *interface,

const char *name);

目的:

参数:

[in]

[out]

过程:

dbus_bool_t dbus_message_append_args(DBusMessage *message,

int first_arg_type,

...);

目的:

参数:

[in]

[out]

过程:

dbus_bool_t dbus_connection_send (DBusConnection *connection,

DBusMessage *message,

dbus_uint32_t *client_serial);

目的:

参数:

[in]

[out]

过程:

void dbus_message_unref(DBusMessage *message);

目的:

参数:

[in]

[out]

过程:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DBus 介绍 的相关文章

  • 【毕设选题】最新51单片机毕业设计项目集合 - 500例

    文章目录 1前言 2 STM32 毕设课题 3 如何选题 3 1 不要给自己挖坑 3 2 难度把控 3 3 如何命名题目 4 最后 1前言 更新单片机嵌入式选题后 不少学弟学妹催学长更新STM32和C51选题系列 感谢大家的认可 来啦 以下
  • Java对文件的基本操作(查找、读取)

    1 读取目录下的所有文件 隐藏的文件一网打尽 快速定位要找的那个文件 查询路径下的所有文件 param path 路径 private static void find String path File file new File path
  • 使用DatagramSocket发送、接收数据(1)

    Java使用DatagramSocket代表UDP协议的Socket DatagramSocket本身只是码头 不维护状态 不能产生IO流 它的唯一作用就是接收和发送数据报 Java使用DatagramPacket来代表数据报 Datagr

随机推荐

  • 给 Typora 改个背景颜色

    因为白色 在多云天气的时候 看上去有的扎眼 所以就想修改一下颜色 但本地的主题 不好看 所以就想简简单单换一个颜色 网上有很多 自定义主题的文章 我懒 只想改背景颜色 不想弄那么多的操作 换成这种颜色 就是好看 哈哈哈 操作 在 typor
  • 清华大学LightGrad-TTS,且流式实现

    论文链接 https arxiv org abs 2308 16569 代码地址 https github com thuhcsi LightGrad 数据支持 针对BZNSYP和LJSpeech提供训练脚本 针对Grad TTS提出两个问
  • stm32外部中断

    目录 1 STM32的外部中断线 2 NVIC嵌套向量中断器 3 外部中断 事件控制器 EXTI 4 STM32CubeMX配置外部中断 1 外部中断是什么 想象一个场景 你在家里玩游戏 这时候突然来电话了 这时你会停止玩游戏去接电话 电话
  • 开源|携程机票 App KMM 跨端 KV 存储库 MMKV-Kotlin

    作者简介 禹昂 携程移动端资深工程师 专注于 Kotlin 移动端跨平台领域 Kotlin 中文社区核心成员 图书 Kotlin 编程实践 译者 一 背景 携程机票移动端研发团队自 2021 年始就一直在移动端实践 Kotlin Multi
  • 关于二进制的练习

    前言 一 二题为牛客网练习 都有题目链接 文章目录 一 两个整数二进制位不同个数 二 输入一个整数 n 输出该数32位二进制表示中1的个数 其中负数用补码表示 三 获取一个整数二进制序列中所有的偶数位和奇数位 分别打印出二进制序列 一 两个
  • 马尔可夫过程

    马尔可夫过程的定义 平稳过程的平稳性保证了未来可以通过过去来预知 而马尔科夫是这样的一类过程 即未来只与现在有关 与过去无关 就是你的过去是什么样子不重要 未来只与自己当下的努力有关 我们只需要知道当前的信息就够了 举一个实际例子比如说卖电
  • 静态路由协议的默认管理距离是_距离矢量路由选择协议

    上一节我们主要讲述了影响路由选择协议的四个因素 路径决策 度量 收敛 负载均衡 也提了一下大多数路由选择协议的分类有距离矢量和链路状态 本节我们主要讲述一下距离矢量路由选择协议 首先说一下 该路由选择协议的由来 由于该路由选择协议通告的方式
  • https网络编程——如何做web的访问控制机制(ACL)

    参考 如何做web的访问控制机制 ACL 地址 https qingmu blog csdn net article details 108286660 spm 1001 2014 3001 5502 目录 ACL含义 例子 具体实现 AC
  • Linux相关的小知识点

    Linux 中每个 TCP 连接最少占用多少内存 详细解释 Linux 内核到底长啥样详细解释
  • GPS模块启动模式

    文章目录 GPS启动模式 1 冷启动 2 热启动 3 温启动 GPS模块举例 GPS启动模式 有3种启动模式 冷启动 温启动 热启动 启动时间 冷启动 gt 温启动 gt 热启动 启动时间越长定位越慢 用户使用体验越差 1 冷启动 冷启动是
  • Segmentation简记1-The Liver Tumor Segmentation Benchmark (LiTS)

    创新点 最主要的创新是建立了一个肝脏CT图像分割数据库 总结 类似于综述加上数据库的介绍 没有细看 医学方面时候会用到
  • 并发编程系列文章-Java线程的创建方式

    文章目录 继承Thread类 实现Runnable接口 使用Callable和Future创建有返回值的线程 使用Executor框架创建线程池 几个关键类的关系图 实战例子 常见的Java线程的4中方式包括 继承Thread类 实现Run
  • 用docker命令时报错,提示:Cannot connect to the Docker daemon at unix:///var/run/docker.sock.

    报错现象 root node02 docker ps Cannot connect to the Docker daemon at unix var run docker sock Is the docker daemon running
  • 工作中报错故障集合

    OOM常见报错排查之堆外内存溢出 报错 ExecutorLostFailure executor xxx exited caused by one of the running tasks Reason Container killed b
  • numpy和torch的一些操作

    1 如何把数据从1维扩充成2维 np expand dims x1 axis 1 或者x1 x1 None 从 2 33075 换成两个 1 33075 x1 x1 None 2 numpy trace array 返回数组沿对角线元素的和
  • Unet网络搭建(Pytorch)

    Unet是一个经典的语义分割网络 常常被用于医学影像的分割 在Unet的网络结构中 可以分为卷积模块 下采样模块以及上采样模块 详见下面的网络结构图 在网络的搭建过程中 也是依照分为三大块这种思路进行搭建 话不多说 直接上代码 import
  • Ubuntu 12.04 64位编译android 4.1.1_r3

    一 初始化编译环境 google推荐的编译环境是在Ubuntu LTS 10 04 但是新的LTS版本12 04已经出来 没必要在旧版本上做文章了 很多行特性和驱动10 04上都没有 例如无线网卡驱动 所以果断选择12 04的LTS版本 对
  • NSGA2算法原理及python实现

    git参考代码 Program Name NSGA II py Description This is a python implementation of Prof Kalyanmoy Deb s popular NSGA II algo
  • Python软件编程等级考试三级——20200913B

    Python软件编程等级考试三级 20200913B 理论 单选题 判断题 实操 第一题 第二题 第三题 理论 单选题 1 关于利用CSV模块对文件进行操作 下列描述不正确的是 A CSV是一种常用的文本格式 使用逗号分隔值的 B CSV模
  • DBus 介绍

    一 什么是 DBus D Bus是一个为应用程序间通信的消息总线系统 用于进程之间的通信 1 1 三层架构 1 函数库libdbus gt gt gt gt gt 用于两个应用程序互相联系和交互消息 2 基于 libdbus 构造的消息总线