`
shaopengxiang
  • 浏览: 5087 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论
阅读更多
D-Bus 体系 (1)
对D-Bus Tutorial进行了一些翻译加上自己的一些理解。

有很多种IPC或者网络通信系统,如:CORBA, DCE, DCOM, DCOP, XML-RPC, SOAP, MBUS, Internet Communications Engine (ICE)等等,可能会有数百种,dbus的目的主要是下面两点:
1.在同一个桌面会话中,进行桌面应用程序之间的通讯
2.桌面程序与内核或者守护进程的通信。

Dbus是一套进程通信体系,它有以下几层:
1.libdbus库,提供给各个应用程序调用,使应用程序具有通信和数据交换的能力,两个应用程序可以直接进行通信,就像是一条socket通道,两个程序之间建立通道之后,就可以通讯了。
2.消息守护进程,在libdbus的基础上创建,可以管理多个应用程序之间的通信。每个应用程序都和消息守护进程建立dbus的链接,然后由消息守护进程进行消息的分派。
3.各种包装库,有libdbus-glib,libdbus-qt等等,目的是将dbus的底层api进行一下封装。

下面有一张图可以很方便说明dbus的体系结构。
dbus

dbus中的消息由一个消息头(标识是哪一种消息)和消息数据组成,比socket的流式数据更方便一些。bus daemon 就像是一个路由器,与各个应用程序进行连接,分派这些消息。bus daemon 在一台机器上有多个实例,第一个实例是全局的实例,类似于sendmail和或者apache,这个实例有很严格的安全限制,只接受一些特定的系统消息,用于系统通信。其他bus daemon是一些会话,用于用户登录之后,在当前会话(session)中进行的通讯。系统的bus daemon 和会话的bus daemon 是分开的,彼此不会互相影响,会话bus daemon 不会去调用系统的bus daemon 。

Native Objects and Object Paths
在不同的编程语言中,都定义了一些“对象”,如java中的java.lang.Object,GLIB中的GObject,QT中的QObject等等。D-BUS的底层接口,和libdbus API相关,是没有这些对象的概念的,它提供的是一种叫对象路径(object path),用于让高层接口绑定到各个对象中去,允许远端应用程序指向它们。object path就像是一个文件路径,可以叫做/org/kde/kspread/sheets/3/cells/4/5等。

Methods and Signals
每个对象都有一些成员,两种成员:方法(methods)和信号(signals),在对象中,方法可以被调用。信号会被广播,感兴趣的对象可以处理这个信号,同时信号中也可以带有相关的数据。每一个方法或者信号都可以用一个名字来命名,如”Frobate” 或者 “OnClicked”。

Interfaces
每个对象都有一个或者多个接口,一个接口就是多个方法和信号的集合。dbus使用简单的命名空间字符串来表示接口,如org.freedesktop.Introspectable。可以说dbus接口相当于C++中的纯虚类。

Proxies
代理对象用于模拟在另外的进程中的远端对象,代理对象像是一个正常的普通对象。d-bus的底层接口必须手动创建方法调用的消息,然后发送,同时必须手动接受和处理返回的消息。高层接口可以使用代理来替换这些,当调用代理对象的方法时,代理内部会转换成dbus的方法调用,等待消息返回,对返回结果解包,返回给相应的方法。可以看看下面的例子,使用dbus底层接口编写的代码:
Message message = new Message("/remote/object/path", "MethodName", arg1, arg2);
Connection connection = getBusConnection();
connection.send(message);
Message reply = connection.waitForReply(message);
if (reply.isError()) {

} else {
Object returnValue = reply.getReturnValue();
}
使用代理对象编写的代码:
Proxy proxy = new Proxy(getBusConnection(), "/remote/object/path");
Object returnValue = proxy.MethodName(arg1, arg2);
客户端代码减少很多。


D-Bus 体系 (2)

Bus Names
当一个应用程序连接上bus daemon时,daemon会分配一个唯一的名字给它。以冒号(:)开始,这些名字在daemon的生命周期中是不会改变的,可以认为这些名字就是一个 IP地址。当这个名字映射到应用程序的连接上时,应用程序可以说拥有这个名字。同时应用可以声明额外的容易理解的名字,比如可以取一个名字 com.mycompany.TextEditor,可以认为这些名字就是一个域名。其他应用程序可以往这个名字发送消息,执行各种方法。

名字还有第二个重要的用途,可以用于跟踪应用程序的生命周期。当应用退出(或者崩溃)时,与bus的连接将被OS内核关掉,bus将会发送通知,告诉剩余的应用程序,该程序已经丢失了它的名字。名字还可以检测应用是否已经启动,这往往用于只能启动一个实例的应用。

Addresses
使用d-bus的应用程序既可以是server也可以是client,server监听到来的连接,client连接到server,一旦连接建立,消息就可以流转。如果使用dbus daemon,所有的应用程序都是client,daemon监听所有的连接,应用程序初始化连接到daemon。

dbus地址指明server将要监听的地方,client将要连接的地方,例如,地址:unix:path=/tmp/abcdef表明 server将在/tmp/abcdef路径下监听unix域的socket,client也将连接到这个socket。一个地址也可以指明是 TCP/IP的socket,或者是其他的。

当使用bus daemon时,libdbus会从环境变量中(DBUS_SESSION_BUS_ADDRESS)自动认识“会话daemon”的地址。如果是系统 daemon,它会检查指定的socket路径获得地址,也可以使用环境变量(DBUS_SESSION_BUS_ADDRESS)进行设定。

当dbus中不使用daemon时,需要定义哪一个应用是server,哪一个应用是client,同时要指明server的地址,这不是很通常的做法。

Big Conceptual Picture
要在指定的对象中调用指定的方法,需要知道的参数如下:
Address -> [Bus Name] -> Path -> Interface -> Method
bus name是可选的,除非是希望把消息送到特定的应用中才需要。interface也是可选的,有一些历史原因,DCOP不需要指定接口,因为DCOP在同一个对象中禁止同名的方法。

Messages - Behind the Scenes
如果使用dbus的高层接口,就可以不用直接操作这些消息。DBUS有四种类型的消息:
1.方法调用(method call) 在对象上执行一个方法
2.方法返回(method return)返回方法执行的结果
3.错误(error)调用方法产生的异常
4.信号(signal)通知指定的信号发生了,可以想象成“事件”。

要执行 D-BUS 对象的方法,需要向对象发送一个方法调用消息。它将完成一些处理并返回一个方法返回消息或者错误消息。信号的不同之处在于它们不返回任何内容:既没有“信号返回”消息,也没有任何类型的错误消息。

每个消息都有一个消息头,包含多个字段,有一个消息体,包含多个参数。可以认为消息头是消息的路由信息,消息体作为一个载体。消息头里面的字段包含发送的bus name,目标bus name,方法或者信号名字等,同时消息头里面定义的字段类型规定了消息体里面的数据格式。例如:字符“i”代表了”32-bit integer”,“ii”就代表了消息体里面有两个”32-bit integer”。

Calling a Method - Behind the Scenes
在dbus中调用一个方法包含了两条消息,进程A向进程B发送方法调用消息,进程B向进程A发送应答消息。所有的消息都由daemon进行分派,每个调用的消息都有一个不同的序列号,返回消息包含这个序列号,以方便调用者匹配调用消息与应答消息。调用消息包含一些参数,应答消息可能包含错误标识,或者包含方法的返回数据。

方法调用的一般流程:
1.使用不同语言绑定的dbus高层接口,都提供了一些代理对象,调用其他进程里面的远端对象就像是在本地进程中的调用一样。应用调用代理上的方法,代理将构造一个方法调用消息给远端的进程。
2.在DBUS的底层接口中,应用需要自己构造方法调用消息(method call message),而不能使用代理。
3.方法调用消息里面的内容有:目的进程的bus name,方法的名字,方法的参数,目的进程的对象路径,以及可选的接口名称。
4.方法调用消息是发送到bus daemon中的。
5.bus daemon查找目标的bus name,如果找到,就把这个方法发送到该进程中,否则,daemon会产生错误消息,作为应答消息给发送进程。
6.目标进程解开消息,在dbus底层接口中,会立即调用方法,然后发送方法的应答消息给daemon。在dbus高层接口中,会先检测对象路径,接口,方法名称,然后把它转换成对应的对象(如GObject,QT中的QObject等)的方法,然后再将应答结果转换成应答消息发给daemon。
7.bus daemon接受到应答消息,将把应答消息直接发给发出调用消息的进程。
8.应答消息中可以包容很多返回值,也可以标识一个错误发生,当使用绑定时,应答消息将转换为代理对象的返回值,或者进入异常。

bus daemon不对消息重新排序,如果发送了两条消息到同一个进程,他们将按照发送顺序接受到。接受进程并需要按照顺序发出应答消息,例如在多线程中处理这些消息,应答消息的发出是没有顺序的。消息都有一个序列号可以与应答消息进行配对。

Emitting a Signal - Behind the Scenes
在dbus中一个信号包含一条信号消息,一个进程发给多个进程。也就是说,信号是单向的广播。信号可以包含一些参数,但是作为广播,它是没有返回值的。

信号触发者是不了解信号接受者的,接受者向daemon注册感兴趣的信号,注册规则是”match rules”,记录触发者名字和信号名字。daemon只向注册了这个信号的进程发送信号。

信号的一般流程如下:
1.当使用dbus底层接口时,信号需要应用自己创建和发送到daemon,使用dbus高层接口时,可以使用相关对象进行发送,如Glib里面提供的信号触发机制。
2.信号包含的内容有:信号的接口名称,信号名称,发送进程的bus name,以及其他参数。
3.任何进程都可以依据”match rules”注册相关的信号,daemon有一张注册的列表。
4.daemon检测信号,决定哪些进程对这个信号感兴趣,然后把信号发送给这些进程。
5.每个进程收到信号后,如果是使用了dbus高层接口,可以选择触发代理对象上的信号。如果是dbus底层接口,需要检查发送者名称和信号名称,然后决定怎么做。
分享到:
评论

相关推荐

    dbus绿色版支持Windows10,基于dbus-1.13.6编译

    DBus,全称Desktop Bus,是Linux桌面环境中的一个核心组件,用于进程间通信(IPC,Inter-Process Communication)。它提供了一种高效、轻量级的方式来让不同进程之间交换信息,协调工作。DBus的设计使得应用程序无需...

    多线程调用DBUS服务注意事项

    多线程调用DBUS服务注意事项 多线程调用DBUS服务是一个复杂的任务,需要遵循一些重要的注意事项,以确保正确地调用DBUS服务。下面是多线程调用DBUS服务的四个重要注意事项: 1. 多线程初始化 在多线程环境中调用...

    ARM平台下交叉编译的DBUS1.2的代码和库

    DBUS(Desktop Bus)是一个用于进程间通信(IPC)的轻量级消息总线,广泛应用于Linux桌面环境和其他服务之间的通信。在ARM平台上交叉编译DBUS1.2,可以为基于Linux的移动设备提供强大的通信支持。 首先,"dbus-...

    2023 最新在 centos7上可用的 dbus rpm包

    centos7 可使用的 dbus rpm包 包含 dbus 与 dbus-libs 两个包,一个是长期支持版 1.12 一个是 最新版 1.15 安装可以先卸载自带的rpm包 rpm -e dbus --nodeps;rpm -e dbus-libs --nodeps 卸载完成后安装新版本即可...

    dbus 使用介绍,包含一个例子,包括配置文件介绍及自启动介绍

    dbus_bool_t dbus_connection_send(DBusConnection *connection, DBusMessage *message, dbus_uint32_t *serial); ``` **参数**: - `connection`:连接描述符。 - `message`:要发送的消息。 - `serial`:发送消息...

    QtDbus资料集合

    QtDbus是Qt框架下与DBus交互的模块,它允许Qt应用程序与其他进程通过DBus协议进行通信。DBus是一种轻量级的消息传递系统,常用于Linux和其他类UNIX系统中的进程间通信(IPC)。QtDbus提供了方便的API,使得Qt开发者...

    dbus-glib使用教程

    其形如一个 DBUS 代理服务器,由它进行所有 DBUS 消息的遍历与转发,服务端与消息发送端只需要向 DBUS deamon 申请注册唯一的 DBUS name 、绑定 GOBJECT 后,DBUS deamon 就会将申请连到该 DBUS name 的 DBUS 信息...

    linux DBUS 实例讲解

    ### Linux DBUS 实例讲解 #### 一、DBUS 是什么? D-Bus是一种轻量级的进程间通信(IPC)机制,专为Linux和其他类Unix操作系统设计,主要用于桌面环境中不同应用程序之间的通信以及应用程序与系统内核之间的通信。相...

    dbus编译后的package

    DBus是Linux系统中的一种消息总线服务,它允许不同进程之间进行通信,是系统服务、应用程序间交互的重要工具。在Linux环境中,DBus常用于启动、停止服务,传递事件,以及在程序之间共享数据。"dbus编译后的package...

    qt for windows版本下编译qtdbus模块

    ### Qt for Windows 版本下编译 QtDBus 模块 #### 背景与目的 Qt 是一个跨平台的应用程序开发框架,广泛应用于桌面应用的构建。Qt 提供了一系列的功能模块来支持开发者的需求,其中之一就是 QtDBus。QtDBus 是用于...

    DBUS API说明文档

    ### DBUS API说明文档知识点详解 #### 一、引言:DBUS API概览 DBUS API(D-Bus Application Programming Interface)是用于Linux和其他类Unix操作系统中的进程间通信(IPC)的一种机制,它允许不同应用程序之间...

    dbus的c++封装以及多进程dbus双向通信例程

    主要是对dbus进行c++封装成了一个dbus类,对外保留发送和接收的接口,方便使用;另外实现多进程dbus的双向通信测试,详细说明见博客<<Dbus 的编译(移植)以及双向通信使用例程>>

    polkit+dbus示例

    提供一个dbus服务,有root权限 普通程序可以通过它作些root才能做的事---此例子为写文件 但是必须先要通过认证 org.polkit.example.conf: 名为org.polkit.example的bus的策略 org.polkit.example.policy 注册action...

    dbus-core详解

    DBus-core详解: D-Bus,全称为Desktop Bus,是一种低延迟、异步的IPC(进程间通信)协议。它主要用于Linux、BSD以及其他自由的类UNIX系统。D-Bus的目的是作为各种早期临时机制的替代品,这些机制在Linux桌面早期...

    Go-dbus-原生Go绑定D-Bus消息总线系统

    Go-dbus是Go语言对D-Bus消息总线系统的原生绑定,允许Go开发者与D-Bus服务进行交互。D-Bus是一种跨进程通信机制,常用于Linux桌面环境中的服务间通信,它提供了低级别的消息传递和接口定义,使得应用程序能够以标准...

    QT中DBUS的用法

    QT中的DBUS是一种在Linux操作系统下进行进程间通信(IPC)的强大工具,它允许不同的应用程序之间交换信息和服务。DBUS由Qt库提供支持,使得开发者能够轻松地在Qt应用程序中集成这种通信机制。以下是对QT中DBUS用法的...

    DBus_C_API_Lowlevel

    DBus是Linux系统中一个用于进程间通信(IPC)的框架,它允许应用程序之间发送和接收消息。DBus C API是直接与DBus协议交互的底层接口,适用于需要深度控制和高效编程的场景。在这个“DBus_C_API_Lowlevel”压缩包中...

    dbus example for low api

    DBus是Linux系统中的一种消息总线服务,它允许不同的应用程序之间进行通信。在这个"dbus example for low api"中,我们将探讨如何使用DBus的低级API来实现一个简单的信号(signal)发送和方法(method)调用的示例。...

    DBUS-GLIB 说明文档

    DBUS-GLIB是DBUS消息总线系统的GLib绑定,它是一个为C语言编写的轻量级库,用于在应用程序中实现进程间通信(IPC)。DBUS是一种用于应用程序间通信的总线系统,通常用于Linux桌面环境中。GLib是一个广泛使用的C库,...

    基于dbus-glib注册总线接口实例

    DBus 是一个轻量级的消息总线系统,允许不同进程之间交换消息,而DBus-Glib 是一个 C 语言库,它为DBus 提供了更方便的绑定,尤其适合用在 GLib 和 GTK+ 的应用程序中。在这个实例中,我们将探讨如何在 C/C++ 中使用...

Global site tag (gtag.js) - Google Analytics