dbus总线通信的原理和使用

article/2025/10/1 4:21:25

1.什么是D-Bus

D-Bus是一种高级的进程间通信机制,它由freedesktop.org项目提供,使用GPL许可证发行。D-Bus最主要的用途是在Linux桌面环境为进程提供通信,同时能将Linux桌面环境和Linux内核事件作为消息传递到进程。注册后的进程可通过总线接收或传递消息,进程也可注册后等待内核事件响应,例如等待网络状态的转变或者计算机发出关机指令。目前,D-Bus已被大多数Linux发行版所采用,开发者可使用D-Bus实现各种复杂的进程间通信任务。

2.D-Bus的相关概念

D-Bus是一个消息总线系统,其功能已涵盖进程间通信的所有需求,并具备一些特殊的用途。D-Bus是三层架构的进程间通信系统,其中包括:

接口层:接口层由函数库libdbus提供,进程可通过该库使用D-Bus的能力。

总线层:总线层实际上是由D-Bus总线守护进程提供的。它在Linux系统启动时运行,负责进程间的消息路由和传递,其中包括Linux内核和Linux桌面环境的消息传递。

包装层:包装层一系列基于特定应用程序框架的Wrapper。

Linux发行版都会提供两种Message Bus:System Bus和Session Bus。System Bus 主要用于内核和一些系统全局的service之间通信;Session Bus 主要用于桌面应用程序之间的通信。

dbus的通信结构图如下图所示:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56CB5Yac6aOe6aOe,size_20,color_FFFFFF,t_70,g_se,x_16

dbus总线通信,通过分层分级的方式实现各种各样的复杂进程间通信。dbus通信分为三层:Service、Object、Interface。

Service

应用程序注册的形如"com.mycompany.myapp"的名字为程序与D-bus总线的连接的名称,用来对应用程序进行定位。相当于对程序的连接起了一个比较好记得地址,类似于网站的域名。应用程序和DBus之间的连接也被称为Service。

Object

当应用程序连接到Message Bus上时,该应用程序可以在Bus上创建多个Object(我们可以把D-Bus的object理解成面向对象语言里的object)。Service通过Object 为其他应用程序提供访问接口。因为在Message Bus上,一个应用程序可以对应多个Object,所以不同的Object必须由Object Path(类似于文件系统的路径)来区分。Object Path的格式如"/component/user"。

Serivce和Object Path之间相互独立,没有任何关联,注册时可以根据需要命名.

Interface

D-Bus通过Signal/Method来发送和接收Message。Signal/Method可以理解为QT中的Signal/Slot这个概念。一个Object可以提供多个Method/Signal,这些Method/Signal的集合又组成了Interface。

因此,D-Bus的这些概念从大到小可以表示为:dbus->Service->Object->[Interface]-> Method/Signal。

在程序之间的通讯过程中,我们通过Service,Object,Interface组合起来,找到信号需要执行的应用程序中的代码。

 

3.D-Bus在Qt中的使用方法

服务端的程序

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include "handler.h"namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();private:Ui::Widget *ui;Handler m_handler;public slots:void service_get(QString st);void send_msg();
signals:void send_to_client(QString);};#endif // WIDGET_H

 

#include "widget.h"
#include "ui_widget.h"
#include "handler.h"
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusMessage>
#include <QDebug>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);QDBusConnection bus = QDBusConnection::sessionBus();//注册名称为domm.test的服务QDBusConnection::sessionBus().unregisterService("domm.test");if(!bus.registerService("domm.test")){qDebug() << bus.lastError().message();exit(1);}//注册名路径为/ceshi/registry的Object//导出对应的槽函数和信号bus.registerObject("/ceshi/registry", this,QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals);//将/ceshi/registry对象com.citos.test2接口下的send_to_service信号//关联对应的槽函数      QDBusConnection::sessionBus().connect(QString(""),QString("/ceshi/registry"),"com.citos.test2","send_to_service",this,SLOT(service_get(QString)));connect(ui->sendBtn, SIGNAL(clicked(bool)),this ,SLOT(send_msg()));setWindowTitle("服务端");
}Widget::~Widget()
{delete ui;
}void Widget::service_get(QString st)
{ui->receive_LineEdit->clear();ui->receive_LineEdit->setText(st);
}void Widget::send_msg()
{QString content = ui->send_LineEdit->text();//创建针对/ceshi/registry对象中com.citos.test1接口下的//send_to_client信号QDBusMessage message = QDBusMessage::createSignal("/ceshi/registry","com.citos.test1","send_to_client");message << content;QDBusConnection::sessionBus().send(message);ui->send_LineEdit->clear();
}
#include "widget.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56CB5Yac6aOe6aOe,size_14,color_FFFFFF,t_70,g_se,x_16

客户端程序

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QtDBus/QDBusConnection>namespace Ui {
class Widget;
}
class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();private slots:void Client_get(QString st);void Send_Msg();private:Ui::Widget *ui;
};#endif // WIDGET_H
#include "widget.h"
#include "ui_widget.h"#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusMessage>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);//将Serivce(domm.test)Object(/ceshi/registry)Interface(com.citos.test2)//发送的信号send_to_client关联到槽函数Client_getQDBusConnection::sessionBus().connect(QString("domm.test"), QString("/ceshi/registry"),"com.citos.test2","send_to_client",this,SLOT(Client_get(QString)));connect(ui->sendBtn, SIGNAL(clicked(bool)),this, SLOT(Send_Msg()));setWindowTitle("客户端");
}Widget::~Widget()
{delete ui;
}void Widget::Send_Msg()
{QString msg = ui->sendLineEdit->text();//发送Object(/ceshi/registry)Interface(com.citos.test2)下的信号//send_to_service到服务端QDBusMessage dbusMsg = QDBusMessage::createSignal("/ceshi/registry","com.citos.test2", "send_to_service");dbusMsg << msg;QDBusConnection::sessionBus().send(dbusMsg);ui->sendLineEdit->clear();
}void Widget::Client_get(QString st)
{ui->ReceiveLineEdit->clear();ui->ReceiveLineEdit->setText(st);
}
#include "widget.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA56CB5Yac6aOe6aOe,size_13,color_FFFFFF,t_70,g_se,x_16

4.dbus调试工具

//linux下通过dbus-monitor命令来监测系统的dbus消息
dbus-monitor [--system | --session | --address ADDRESS] 
[--monitor | --profile | --pcap | --binary ] [watch expressions]--system   监控系统的dbus消息
--session  监控所有的会话消息(默认)
--profile  使用简要的输出格式
--monitor  使用监控的输出格式(默认)//监听特定服务特定对象特定接口发送的特定消息
//监听org.cehsi.info服务,在interface接口下发送的信号
dbus-monitor "type='signal',sender='org.cehi.info',interface='org.cehsi.test'"
type:调用的类型,包括:method_call. signal
sender:用来筛选发送者
interface:用来指定对应的接口

 

 


http://chatgpt.dhexx.cn/article/DuJcpuEI.shtml

相关文章

制作maven-archeType

制作maven-archeType 项目背景 解决每次开发新项目&#xff0c;要创建很多目录结构或者从老项目中修改包名&#xff0c;pom等&#xff0c;所以就自己制作一个项目骨架&#xff0c;便于以后新项目目录结构生成。 制作maven-archeType 1.自己开发一个maven-archeType项目&…

[WARNING] No archetype found in remote catalog. Defaulting to internal catalog(已解决)

前言&#xff1a; 遇到问题后&#xff0c;首先&#xff0c;在网络上查找答案。结果告诉我&#xff0c;让我重启IDEA&#xff0c;可是我使用的是CMD命令行&#xff0c;根本没有使用IDEA。或者&#xff0c;告诉我如何操作&#xff0c;却没有解释问题发生的根本原因。于是&#xf…

idea自定义archetype及错误处理

介绍&#xff1a;公司内部会制定自己的规范及包结构。当创建新项目的时候就需要选择骨架&#xff0c;即可生成包结构。本文章简单介绍如何创建&#xff0c;解决遇到的各种问题。 一、创建项目。 idea点击file--->new--->project--->点击左侧的Spring initializr- 图2…

Maven 三种archetype说明合集

Maven 三种archetype说明合集【转载】_maven-archetype-quickstart_太阳神LoveU的博客-CSDN博客 新建Maven project项目时&#xff0c;需要选择archetype。 那么&#xff0c;什么是archetype&#xff1f; archetype的意思就是模板原型的意思&#xff0c;原型是一个Maven项目模…

maven自定义archetype

在开发过程中我们经常会创建一系列结构类似的新项目&#xff0c;这些项目结构和基础配置基本或完全一致&#xff0c;maven就提供了archetype类型来规定新建项目的结构及基础配置&#xff0c;利用archetype就可以快速简单的搭建新项目。 一、创建Maven项目的一般步骤 一般情况下…

自定义Maven Archetype模板工程

文章目录 Maven Archetype介绍什么是Maven Archetype为什么要有模板工程创建模板工程的三种方式 常用的archetypemaven-archetype-quickstartmaven-archetype-webapp 自定义一个Maven模板工程生成模板上传模板到仓库(此步骤可选) 使用模板工程 源码地址&#xff1a;https://git…

如何选择创建Maven的archetype

前言&#xff1a; 在使用IDEA的Maven插件创建我们的maven项目时提供了如图所示的原型&#xff0c;为我们快速创建合适的项目提供了很大的帮助。下面我们将详细介绍各个archetype。 官网对archetype(原型)的介绍&#xff1a; http://maven.apache.org/guides/introduction/in…

Maven model archetype说明

前言 新建一个model&#xff0c;其中有一个选项“Create from archetype”感觉很奇怪&#xff0c;我就来了解一下这些内容&#xff0c;做一下笔记&#xff0c; 什么是Archetype Archetype翻译过来就是&#xff1a;骨架&#xff0c;项目工程骨架。 Archetype是Maven工程的模板…

Maven自定义Archetype项目模板

前言&#xff1a;在某课网上学习到可以使用命令mvn archetype:create-from-project来创建自己的项目模板&#xff08;文中提及的项目模板即 原型 archetype&#xff09;&#xff0c;对此我十分感兴趣。但是&#xff0c;遗憾的是&#xff0c;老师没有介绍如何去构建这样一个特殊…

Maven-Archetype Catalog

当用户以不指定Archetype坐标的方式使用maven-archetype-plugin的时候&#xff0c;会得到一个Archetype列表供选择&#xff0c;这个列表的信息来源于一个名为archetype-catalog.xml的文件&#xff0c;如&#xff1a; archetype-catlog.xml能提供Archetype的信息&#xff0c;那么…

Idea archetype介绍

一、背景 Idea创建项目时&#xff0c;被一堆archetype混淆视听&#xff0c;犹豫不决决定彻底弄懂他 1.关键词 Archetype: 骨架Maven: Java代码编译时的一个工具&#xff08;软件讲究运行时、和编译时两种状态&#xff09; 2.网友介绍 Archetype是Maven工程的模板工具包。一…

Maven Archetype

目录 Maven Archetype工程结构创建Maven Archetype创建支持生成多模块的Maven Archetype在idea中添加自定义Maven Archetype 最开始接触到maven archetype&#xff0c;是在通过idea创建project时&#xff0c;可以选择Maven -> Create from archetype&#xff0c; 在输入proj…

自定义idea archetype

编写 archetype 元数据 通过plugin从现有项目中导出 1、引入plugin <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-archetype-plugin</artifactId><version>3.2.0</version></plugin>2、通过maven…

Maven 三种archetype说明

新建Maven project项目时,需要选择archetype。 那么,什么是archetype? archetype的意思就是模板原型的意思,原型是一个Maven项目模板工具包。一个原型被定义为从其中相同类型的所有其它事情是由一个原始图案或模型。名称配合,因为我们正在努力提供一种系统,该系统提供了…

maven中archetype(原型)的使用及创建

当我们在idea中创建项目时&#xff0c;经常会见到如下界面选择&#xff1a; archetype也就是原型&#xff0c;准确说是一个项目模板&#xff0c;我们可以根据该模板来生成项目。 我就不介绍图形界面的创建方式了&#xff0c;一步一步太啰嗦了&#xff0c;我们用命令方式创建。…

创建自定义的archetype(项目模板)

一、archetype简介 Archetype是一个Maven项目的模板工具包&#xff0c;它定义了一类项目的基本架构。Archetype为开发人员提供了创建Maven项目的模板&#xff0c;同时它也可以根据已有的Maven项目生成参数化的模板。通过archetype&#xff0c;开发人员可以很方便地将一类项目的…

Maven创建时archetype的选择说明

新建Maven project项目时&#xff0c;需要选择archetype。 那么&#xff0c;什么是archetype&#xff1f; archetype的意思就是模板原型的意思&#xff0c;原型是一个Maven项目模板工具包。一个原型被定义为从其中相同类型的所有其它事情是由一个原始图案或模型。名称配合&am…

Maven的Archetype简介

简单的说&#xff0c;Archetype是Maven工程的模板工具包。一个Archetype定义了要做的相同类型事情的初始样式或模型。这个名称给我们提供来了一个一致的生成Maven工程的方式。Archetype会帮助作者给用户创建Maven工程模板&#xff0c;并给用户提供生成相关工程模板版本的参数化…

c语言学习--强制类型转换

C语言中关于强制类型转换问题 由于朋友问到&#xff0c;所以整理了一份&#xff0c;若关于一些认识有错误还望指出...... ● 如果一个运算符两边的运算数类型不同&#xff0c;先要将其转换为相同的类型&#xff0c;即较低类型转换为较高类型&#xff0c;然后再参加运算&#xf…

列举三种强制类型转换

1 强制类型转换—String 这里主要列举了两种强制转换为字符串类型的方法&#xff0c;我们也在log控制台中验证了新的类型。 但是注意&#xff1a;null 和 undefined 这两个值没有 toString()方法。 2 强制类型转换—Number 这里我为大家列举了三种方法&#xff0c;但是注意后…