Linux DBUS服务器端程序

article/2025/10/1 3:55:57

DBus 服务器端接收方式

DBus 服务器端用来接收signal和method调用。从收集的资料中发现,主要有三种接收方式。

一,采用while循环,监听dbus_connection_read_write()函数。有消息到来时在循环内部进行处理。优点是结构简单,处理方便。程序结构如下图。

/*
test.signal.server(bus name)|----test.signal.Type(interface1)|   ||   ----FunctionOne(method1)|   ||   ----FunctionTwo(method2)----org.freedesktop.DBus.Introspectable(interface3)|   ||   ----Introspect(method3)response to interface(test.signal.Type) signal(Test)
response to interface(test.signal.Type2) signal(TestString)
response to interface(test.signal.Type) signal(MulType)
*/
#include <iostream>
#include <stdlib.h>
#include <dbus/dbus.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>const int RES_SUCCESS = -1;
const int RES_FAILED = 0;
using namespace std;
//sprintf (answer, "Sum is %d", i + j);const char *const SERVER_BUS = "test.signal.server";
const char *const INTERFACE1 = "test.signal.Type";
const char *const INTERFACE2 = "test.signal.Type2";
const char *const OBJECTPATH1 = "/test/signal/server";
const char *const METHOD_1 = "FunctionOne";
const char *const METHOD_2 = "FunctionTwo";
const char *const SIGNAL_1 = "Test";
const char *const SIGNAL_MUL = "MulType";
const char *const SIGNAL_STRING = "TestString";
const char *const SIGNAL_ARRAY = "Array";int my_dbus_initialization(char const *_bus_name, DBusConnection **_conn)
{DBusError err;int ret;dbus_error_init(&err);*_conn = dbus_bus_get(DBUS_BUS_SESSION, &err);if (dbus_error_is_set(&err)){cout<<"Connection Error:"<<err.message<<endl;dbus_error_free(&err);return RES_FAILED;}ret = dbus_bus_request_name(*_conn, _bus_name,DBUS_NAME_FLAG_REPLACE_EXISTING, &err);if (dbus_error_is_set(&err)){cout<<"Replace error"<<err.message<<endl;dbus_error_free(&err);return RES_FAILED;}if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret){cout<<"dbus is not primary own"<<endl;return RES_FAILED;}return RES_SUCCESS;
}void* wait_signal(void *)
{DBusError err;DBusMessage *msg;DBusMessageIter args;dbus_error_init(&err);DBusConnection *conn;if (RES_FAILED == my_dbus_initialization(SERVER_BUS, &conn)){exit(1);}char match_str[64];memset(match_str, 0, sizeof(match_str));sprintf (match_str, "type='signal',interface='%s'", INTERFACE1);dbus_bus_add_match(conn, match_str,&err);                       // add rule to matchmemset(match_str, 0, sizeof(match_str));sprintf (match_str, "type='signal',interface='%s'", INTERFACE2);dbus_bus_add_match(conn, match_str, &err);                      // add rule to matchdbus_connection_flush(conn);if (dbus_error_is_set(&err)){cout<<"dbus_bus_add_match err "<<err.message<<endl;dbus_error_free(&err);return NULL;// RES_FAILED;}cout<<"server start"<<endl;while(1){//cout<<"one circle"<<endl;//dbus_connection_read_write(conn, 0);if (!dbus_connection_read_write(conn, 0)){break;}usleep(1);msg = dbus_connection_pop_message(conn);    // receive messageif (NULL == msg){usleep(1);//sleep(1);continue;}if (dbus_message_is_signal(msg, INTERFACE1, SIGNAL_1)){if (!dbus_message_iter_init(msg, &args)){cout<<"dbus_message_iter_init error, msg has no arguments!"<<endl;continue;}if (DBUS_TYPE_UINT32 == dbus_message_iter_get_arg_type(&args)){//cout<<"not a uint 32 type!"<<endl;dbus_uint32_t my_age = 0;dbus_message_iter_get_basic(&args, &my_age);cout<<"Got signal with value "<<my_age<<endl;}else {cout<<SIGNAL_1<<" unhandle type"<<endl;}}else if (dbus_message_is_signal(msg, INTERFACE1, SIGNAL_ARRAY)){cout<<SIGNAL_ARRAY<<" is called"<<endl;if (!dbus_message_iter_init(msg, &args)){cout<<"dbus msg iter init failed"<<endl;continue;}DBusMessageIter subIter;dbus_message_iter_recurse(&args, &subIter);int *intArray = NULL;int elementNum = 0;dbus_message_iter_get_fixed_array(&subIter, &intArray, &elementNum);for (int i=0; i<elementNum; ++i){cout<<intArray[i]<<endl;}}else if (dbus_message_is_signal(msg, INTERFACE1, SIGNAL_MUL)){if (!dbus_message_iter_init(msg, &args)){cout<<"dbus_message_iter_init error, msg has no arguments!"<<endl;continue;}do {if (DBUS_TYPE_UINT32 == dbus_message_iter_get_arg_type(&args)){dbus_uint32_t my_age = 0;dbus_message_iter_get_basic(&args, &my_age);cout<<"Got signal with value "<<my_age<<endl;}if (DBUS_TYPE_STRING == dbus_message_iter_get_arg_type(&args)){char* myString = NULL;dbus_message_iter_get_basic(&args, &myString);cout<<"Get signal with string:"<<myString<<endl;}if (DBUS_TYPE_BOOLEAN == dbus_message_iter_get_arg_type(&args)){dbus_bool_t boolFlag = false;dbus_message_iter_get_basic(&args, &boolFlag);cout<<"Get bool value: "<<boolFlag<<endl;}/*if (DBUS_TYPE_ARRAY == dbus_message_iter_get_arg_type(&args)){cout<<"get an array"<<endl;int *intArray = NULL;int elementNum = 0;dbus_message_iter_get_fixed_array(&args, &intArray, &elementNum);for (int i=0; i<elementNum; ++i){cout<<intArray[i]<<endl;}}*/}while(dbus_message_iter_next(&args));}else if (dbus_message_is_signal(msg, INTERFACE2, SIGNAL_STRING)){if (!dbus_message_iter_init(msg, &args)){cout<<"dbus_message_iter_init error, msg has no arguments!"<<endl;}else if (DBUS_TYPE_STRING == dbus_message_iter_get_arg_type(&args)){char* myString = NULL;dbus_message_iter_get_basic(&args, &myString);cout<<"Get signal with string:"<<myString<<endl;}else {cout<<"unhandle type"<<endl;}}else if (dbus_message_is_method_call(msg, INTERFACE1, METHOD_1)){char* param = NULL;if (dbus_message_get_args(msg, &err, DBUS_TYPE_STRING,&param, DBUS_TYPE_INVALID)){cout<<"Method "<<METHOD_1<<" is called and get string: "<<param<<endl;}else{cout<<"error call function"<<endl;}}else if (dbus_message_is_method_call(msg, INTERFACE1, METHOD_2)){char* param = NULL;if (dbus_message_get_args(msg, &err, DBUS_TYPE_STRING,&param, DBUS_TYPE_INVALID)){cout<<"Method "<<METHOD_2<<" is called and get string: "<<param<<endl;}else{cout<<"error call function"<<endl;}}else if (dbus_message_is_method_call(msg, "org.freedesktop.DBus.Introspectable", "Introspect")){DBusMessage *reply;const char *introspection_data = "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" \n""\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n""<node>\n""  <interface name=\"org.freedesktop.DBus.Introspectable\">\n""    <method name=\"Introspect\">\n""      <arg name=\"data\" direction=\"out\" type=\"s\"/>\n""    </method>\n""  </interface>\n""  <interface name=\"test.signal.Type\">\n""    <method name=\"FunctionOne\">\n""      <arg direction=\"in\" type=\"s\"/>\n""    </method>\n""    <method name=\"FunctionTwo\">\n""      <arg direction=\"in\" type=\"s\"/>\n""    </method>\n""  </interface>\n""</node>\n";cout<<introspection_data<<endl;reply = dbus_message_new_method_return(msg);dbus_message_append_args(reply, DBUS_TYPE_STRING,&introspection_data,DBUS_TYPE_INVALID);dbus_connection_send(conn, reply, NULL);dbus_message_unref(reply);}dbus_message_unref(msg);}
}int main()
{pthread_t id;int ret;ret = pthread_create(&id, NULL, wait_signal, NULL);if (ret != 0){cout<<"create pthread error"<<endl;}pthread_join(id, NULL);return 0;
}

二,在while循环前注册路径。优点是不需要在循环内部处理消息,结构清晰。将处理消息函数放DBusObjectPathVTable结构中。通过DBusObjectPathVTable中的message_function指向处理函数,在处理函数中判断消息类型并处理。程序结构如下图。

/*
test.signal.server(bus name)|----test.signal.Type(interface1)|   ||   ----Test(signal1)|   ||   ----FunctionOne(method1)|   ||   ----FunctionTwo(method2)----test.signal.Type2(interface2)|   ||   ----TestString(signal2)----org.freedesktop.DBus.Introspectable(interface3)|   ||   ----Introspect(method3)
*/
#include <iostream>
#include <stdlib.h>
#include <dbus/dbus.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>const int RES_SUCCESS = -1;
const int RES_FAILED = 0;
using namespace std;const char *const SERVER_BUS = "test.signal.server";
const char *const INTERFACE1 = "test.signal.Type";
const char *const INTERFACE2 = "test.signal.Type2";
const char *const OBJECTPATH1 = "/test/signal/server";
const char *const METHOD_1 = "FunctionOne";
const char *const METHOD_2 = "FunctionTwo";
const char *const SIGNAL_1 = "Test";
const char *const SIGNAL_2 = "TestString";static DBusHandlerResult method_message(DBusConnection *connection, DBusMessage *request);
static void respond_to_introspect(DBusConnection *connection, DBusMessage *request);
static void respond_to_Method_1(DBusConnection *connection, DBusMessage* request);
static void respond_to_Method_2(DBusConnection *connection, DBusMessage* request);
static void respond_to_Signal_1(DBusConnection *connection, DBusMessage* msg);
static void respond_to_Signal_2(DBusConnection *connection, DBusMessage* msg);int my_dbus_initialization(char const *_bus_name, DBusConnection **_conn)
{DBusError err;int ret;dbus_error_init(&err);*_conn = dbus_bus_get(DBUS_BUS_SESSION, &err);if (dbus_error_is_set(&err)){cout<<"Connection Error:"<<err.message<<endl;dbus_error_free(&err);return RES_FAILED;}ret = dbus_bus_request_name(*_conn, _bus_name,DBUS_NAME_FLAG_REPLACE_EXISTING, &err);if (dbus_error_is_set(&err)){cout<<"Replace error"<<err.message<<endl;dbus_error_free(&err);return RES_FAILED;}if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret){return RES_FAILED;}return RES_SUCCESS;
}static void respond_to_introspect(DBusConnection *connection, DBusMessage *request)
{cout<<"called introspect"<<endl;DBusMessage *reply;const char *introspection_data ="<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\" \n""\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n""<node>\n""  <interface name=\"org.freedesktop.DBus.Introspectable\">\n""    <method name=\"Introspect\">\n""      <arg name=\"data\" direction=\"out\" type=\"s\"/>\n""    </method>\n""  </interface>\n""  <interface name=\"test.signal.Type\">\n""    <method name=\"FunctionOne\">\n""      <arg direction=\"in\" type=\"s\"/>\n""    </method>\n""    <method name=\"FunctionTwo\">\n""      <arg direction=\"in\" type=\"s\"/>\n""    </method>\n""  </interface>\n""</node>\n";reply = dbus_message_new_method_return(request);if (!dbus_message_append_args(reply, DBUS_TYPE_STRING,&introspection_data,DBUS_TYPE_INVALID)){fprintf(stderr, "append args error");return;}if (!dbus_connection_send(connection, reply, NULL)){fprintf(stderr, "Out Of Memory!\n");return;}dbus_message_unref(reply);
}static void respond_to_Method_1(DBusConnection *connection, DBusMessage *request)
{DBusError dbus_error;dbus_error_init(&dbus_error);char* param = NULL;if (dbus_message_get_args(request, &dbus_error, DBUS_TYPE_STRING,&param, DBUS_TYPE_INVALID)){cout<<"Method "<<METHOD_1<<" is called and get string: "<<param<<endl;}else{cout<<"error call function"<<endl;}
}static void respond_to_Method_2(DBusConnection *connection, DBusMessage *request)
{DBusError dbus_error;dbus_error_init(&dbus_error);char* param = NULL;if (dbus_message_get_args(request, &dbus_error, DBUS_TYPE_STRING,&param, DBUS_TYPE_INVALID)){cout<<"Method "<<METHOD_2<<" is called and get string: "<<param<<endl;}else{cout<<"error call function"<<endl;}
}static void respond_to_Signal_1(DBusConnection *connection, DBusMessage *msg)
{DBusMessageIter args;if (!dbus_message_iter_init(msg, &args)){cout<<"dbus_message_iter_init error, msg has no arguments!"<<endl;}else if (DBUS_TYPE_UINT32 == dbus_message_iter_get_arg_type(&args)){dbus_uint32_t ivalue = 0;dbus_message_iter_get_basic(&args, &ivalue);cout<<"Got signal with value "<<ivalue<<endl;}else {cout<<"unhandle type"<<endl;}
}static void respond_to_Signal_2(DBusConnection *connection, DBusMessage *msg)
{DBusMessageIter args;if (!dbus_message_iter_init(msg, &args)){cout<<"dbus_message_iter_init error, msg has no arguments!"<<endl;}else if (DBUS_TYPE_STRING == dbus_message_iter_get_arg_type(&args)){char* myString = NULL;dbus_message_iter_get_basic(&args, &myString);cout<<"Get signal with string:"<<myString<<endl;}else {cout<<"unhandle type"<<endl;}
}static DBusHandlerResult method_message(DBusConnection *connection, DBusMessage *message, void *user_data)
{const char *interface_name = dbus_message_get_interface(message);const char *member_name = dbus_message_get_member(message);cout<<interface_name <<" "<< member_name<<endl;if (0 == strcmp("org.freedesktop.DBus.Introspectable", interface_name) &&0 == strcmp("Introspect", member_name)){respond_to_introspect(connection, message);return DBUS_HANDLER_RESULT_HANDLED;}else if (0 == strcmp(INTERFACE1, interface_name) && 0 == strcmp(METHOD_1, member_name)){respond_to_Method_1(connection, message);return DBUS_HANDLER_RESULT_HANDLED;}else if (0 == strcmp(INTERFACE1, interface_name) && 0 == strcmp(METHOD_2, member_name)){respond_to_Method_2(connection, message);return DBUS_HANDLER_RESULT_HANDLED;}else if (0 == strcmp(INTERFACE1, interface_name) && 0 == strcmp(SIGNAL_1, member_name)){cout<<"signal is called"<<endl;respond_to_Signal_1(connection, message);return DBUS_HANDLER_RESULT_HANDLED;}else if (0 == strcmp(INTERFACE2, interface_name) && 0 == strcmp(SIGNAL_2, member_name)){cout<<"signal 2 is called"<<endl;respond_to_Signal_2(connection, message);return DBUS_HANDLER_RESULT_HANDLED;}else{return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;}
}void* wait_signal(void *)
{DBusError err;DBusMessage *msg;DBusMessageIter args;dbus_error_init(&err);DBusConnection *conn;if (RES_FAILED == my_dbus_initialization(SERVER_BUS, &conn)){exit(1);}char match_str[64];memset(match_str, 0, sizeof(match_str));sprintf (match_str, "type='signal',interface='%s'", INTERFACE1);dbus_bus_add_match(conn, match_str,&err);                       // add rule to match//memset(match_str, 0, sizeof(match_str));//sprintf (match_str, "type='signal',interface='%s'", INTERFACE2);//dbus_bus_add_match(conn, match_str, &err);                      // add rule to matchdbus_connection_flush(conn);if (dbus_error_is_set(&err)){cout<<"dbus_bus_add_match err "<<err.message<<endl;return NULL;// RES_FAILED;}cout<<"server start"<<endl;DBusObjectPathVTable vtable;vtable.message_function = method_message;vtable.unregister_function = NULL;dbus_connection_try_register_object_path(conn,OBJECTPATH1,&vtable,NULL,&err);while(1){if (!dbus_connection_read_write_dispatch(conn, 0)){fprintf(stderr, "Noe connected now.\n");break;}usleep(1);}
}int main()
{pthread_t id;int ret;ret = pthread_create(&id, NULL, wait_signal, NULL);if (ret != 0){cout<<"create pthread error"<<endl;}pthread_join(id, NULL);return 0;
}

三,采用select函数监听设备变化,将select函数放在监听循环中。优点是可以同时监听其他消息,如可以监听TCP和UDP。程序结构如下图。

实例


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

相关文章

Linux -dbus总线

下载编译dbus 下载https://dbus.freedesktop.org/releases/dbus/ dbussrc1.14.0-Linux文档类资源-CSDN下载 dbus-1.14.0.tar.xz xz -d dbus-1.14.0.tar.xz tar xvf dbus-1.14.0.tar2.配置编译 ./configure --prefix/data/opensrc/dbus #--prefix/data/opensrc/dbus 指定输…

DBus通讯

linux下进程间通信的方式主要有Pipe(管道)&#xff0c;FIFO(命名管道)&#xff0c;信号&#xff0c;共享内存&#xff0c;消息队列&#xff0c;信号灯等&#xff0c;这些方式各有 各得特点&#xff0c;如管道是linux下命令行中常用的&#xff0c;用于父子进程的通信。但是这些通…

Linux DBUS客户端程序

DBUS客户端程序&#xff0c;发送一个信号&#xff0c;信号携带int型数据。信号的object path为"/test/signal/server"&#xff0c;interface名为 "test.signal.Type"&#xff0c;信号名为"Test"。接收端可以根据这三个属性来判断是否是想接收的信…

四、QtDbus

文章目录 概述一、QtDBus模块Debug备忘单 二、QtDBus类型系统1、QtDBus类型系统简介2、原生类型3、复合类型4、扩展类型系统5、类型系统使用 三、QtDBus常用类1、QDBusMessage2、QDBusConnection3、QDBusInterface4、QDBusReply5、QDBusAbstractAdaptor6、QDBusAbstractInterfa…

Hello Qt——QtDBus快速入门

一、QtDBus简介 QtDBus是一个使用D-Bus协议进行进程间通信的仅在Unix运行的库&#xff0c;是对D-Bus底层API的封装实现。 QtDBus模块提供了使用Qt信号槽机制扩展的接口。要使用QtDBus模块&#xff0c;需要在代码中加入以下代码&#xff1a; #include <QtDBus> 如果使用…

DBUS

DBUS是一种高级的进程间通信机制。DBUS支持进程间一对一和多对多的对等通信&#xff0c;在多对多的通讯时&#xff0c;需要后台进程的角色去分转消息&#xff0c;当一个进程发消息给另外一个进程时&#xff0c;先发消息到后台进程&#xff0c;再通过后台进程将信息转发到目的进…

DBUS是什么 如何使用

DBus提供了一种低延时,低开销,高可用性的进程间通信方式,其以消息作为驱动,采用二进制的协议,实现一对一及多对多的对等通信,避免通信的序列化&#xff08;编码过程&#xff09;过程,提高通信效率.DBus进程通信的核心是提供了一个后台中转守护进程,需要通信的进程首先连接到DBu…

dbus总线通信的原理和使用

1.什么是D-Bus D-Bus是一种高级的进程间通信机制&#xff0c;它由freedesktop.org项目提供&#xff0c;使用GPL许可证发行。D-Bus最主要的用途是在Linux桌面环境为进程提供通信&#xff0c;同时能将Linux桌面环境和Linux内核事件作为消息传递到进程。注册后的进程可通过总线接…

制作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…