使用 dbus 的简单客户端服务器
Posted
技术标签:
【中文标题】使用 dbus 的简单客户端服务器【英文标题】:Simple client server using dbus 【发布时间】:2016-09-03 02:43:23 【问题描述】:我已经使用 dbus 开发了一个客户端服务器应用程序。客户端使用 dbus_message 发送 2 个输入参数,服务器返回总和。我主要对使用 DBusWatch 感兴趣,因此我可以从多个客户端发送并让服务器响应它们。谁能帮我编写代码并解释一下 DbusWatch 是如何工作的?
代码
client.c
#include <stdio.h>
#include <stdlib.h>
#include <dbus/dbus.h>
#include <stdbool.h>
#include <ctype.h>
void caller(int param,int param1)
DBusMessage* msg;
DBusMessageIter args;
DBusConnection* conn;
DBusError err;
DBusPendingCall* pending;
int ret;
int level;
printf("Calling remote method with %d %d\n",param,param1);
// initialiset the errors
dbus_error_init(&err);
// connect to the system bus and check for errors
conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
if (dbus_error_is_set(&err))
fprintf(stderr, "Connection Error (%s)\n", err.message);
dbus_error_free(&err);
if (NULL == conn)
exit(1);
// request our name on the bus
ret = dbus_bus_request_name(conn, "test.client.caller", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
if (dbus_error_is_set(&err))
fprintf(stderr, "Name Error (%s)\n", err.message);
dbus_error_free(&err);
// create a new method call and check for errors
msg = dbus_message_new_method_call("test.server.source", // target for the method call
"/test/method/Object", // object to call on
"test.method.Type", // interface to call on
"Method"); // method name
if (NULL == msg)
fprintf(stderr, "Message Null\n");
exit(1);
// append arguments
dbus_message_iter_init_append(msg, &args);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, ¶m))
fprintf(stderr, "Out Of Memory!\n");
exit(1);
if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, ¶m1))
fprintf(stderr, "Out Of Memory!\n");
exit(1);
// send message and get a handle for a reply
if (!dbus_connection_send_with_reply (conn, msg, &pending, -1)) // -1 is default timeout
fprintf(stderr, "Out Of Memory!\n");
exit(1);
if (NULL == pending)
fprintf(stderr, "Pending Call Null\n");
exit(1);
dbus_connection_flush(conn);
printf("Request Sent\n");
// free message
dbus_message_unref(msg);
// block until we recieve a reply
dbus_pending_call_block(pending);
// get the reply message
msg = dbus_pending_call_steal_reply(pending);
if (NULL == msg)
fprintf(stderr, "Reply Null\n");
exit(1);
// free the pending message handle
dbus_pending_call_unref(pending);
// read the parameters
if (!dbus_message_iter_init(msg, &args))
fprintf(stderr, "Message has no arguments!\n");
else
dbus_message_iter_get_basic(&args, &level);
printf("Got Reply:%d\n",level);
// free reply and close connection
dbus_message_unref(msg);
dbus_connection_close(conn);
int main(int argc, char **argv)
if (argc == 1)
return -1;
else if(argc==3)
int param = atoi(argv[1]);
int param1 = atoi(argv[2]);
caller(param,param1);
else
printf("Number of arguments should be 2 integers\n");
server.c
#include <stdbool.h>
#include <stdlib.h>
#include <dbus/dbus-glib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <dbus-1.0/dbus/dbus.h>
#include <math.h>
void reply_to_method_call(DBusMessage* msg, DBusConnection* conn)
DBusMessage* reply;
DBusMessageIter rootIter;
dbus_uint32_t serial = 0;
dbus_uint32_t a;
dbus_uint32_t b;
dbus_uint32_t sum;
// read the arguments
if (!dbus_message_iter_init(msg,&rootIter))
fprintf(stderr, "Message has no arguments!\n");
dbus_message_iter_get_basic(&rootIter, &a);
printf("Method called with %d\n", a);
if(dbus_message_iter_has_next(&rootIter))
dbus_message_iter_next(&rootIter);
dbus_message_iter_get_basic(&rootIter, &b);
printf("Method called with %d\n", b);
if ( dbus_message_is_method_call( msg, "test.method.Type", "Method" ) )
sum=a+b;
// create a reply from the message
reply = dbus_message_new_method_return(msg);
// add the arguments to the reply
dbus_message_iter_init_append(reply, &rootIter);
if (!dbus_message_iter_append_basic(&rootIter, DBUS_TYPE_INT32, &sum))
fprintf(stderr, "Out Of Memory!\n");
exit(1);
// send the reply && flush the connection
if (!dbus_connection_send(conn, reply, &sum))
fprintf(stderr, "Out Of Memory!\n");
exit(1);
dbus_connection_flush(conn);
// free the reply
dbus_message_unref(reply);
int main()
DBusMessage* msg;
DBusMessage* reply;
DBusMessageIter args;
DBusConnection* conn;
DBusError err;
int ret;
char* param;
printf("Listening for method calls\n");
// initialise the error
dbus_error_init(&err);
// connect to the bus and check for errors
conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
if (dbus_error_is_set(&err))
fprintf(stderr, "Connection Error (%s)\n", err.message);
dbus_error_free(&err);
if (NULL == conn)
fprintf(stderr, "Connection Null\n");
exit(1);
// request our name on the bus and check for errors
ret = dbus_bus_request_name(conn,"test.server.source", DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
if (dbus_error_is_set(&err))
fprintf(stderr, "Name Error (%s)\n", err.message);
dbus_error_free(&err);
// loop, testing for new messages
while (true)
// non blocking read of the next available message
dbus_connection_read_write(conn, 0);
msg = dbus_connection_pop_message(conn);
// loop again if we haven't got a message
if (NULL == msg)
sleep(1);
continue;
if ( dbus_message_has_interface(msg, "test.method.Type") )
reply_to_method_call( msg, conn );
// free the message
dbus_message_unref(msg);
// close the connection
dbus_connection_close(conn);
【问题讨论】:
【参考方案1】:以及构建这些文件的 Makefile;
CC=gcc
CPP=g++
LDFLAGS =-ldbus-1
LDFLAGS+=-ldbus-glib-1
CFLAGS =.
CFLAGS+=-I/usr/include/dbus-1.0
CFLAGS+=-I/usr/lib/x86_64-linux-gnu/dbus-1.0/include
CFLAGS+=-I/usr/include/glib-2.0
CFLAGS+=-I/usr/lib/x86_64-linux-gnu/glib-2.0/include
CFLAGS+=-Wall
CFLAGS+=-Wextra
CFLAGS+=-g
all: server client
rebuild: clean all
%.o: %.c
@echo " CC $^"
$(CC) $(CFLAGS) -c -o $@ $^
server: server.o
@echo " LINK $^"
$(CC) $^ $(LDFLAGS) -o $@
client: client.o
@echo " LINK $^"
$(CC) $^ $(LDFLAGS) -o $@
clean:
rm -f *.o server client
【讨论】:
您能否提供更多背景信息,说明您的答案为何以及如何帮助 OP?以上是关于使用 dbus 的简单客户端服务器的主要内容,如果未能解决你的问题,请参考以下文章