现在的位置: 首页 > 综合 > 正文

DBUS学习实例

2017年09月15日 ⁄ 综合 ⁄ 共 7345字 ⁄ 字号 评论关闭

最近的工作涉及到DBUS通信,所以这里做一下总结,也是即学即用所以了解的没有那么深入,环境搭建这里就不谈了,这里说说具体的操作流程以及代码的实现。

我们这里按CS的模式来讲,我们这里会有两个C文件,一个是服务端代码,一个是客户端代码,对了还有一个XML文件。

首先当然是先写好这两个代码,然后就是编译了,编译首先先要编译这个XML文件,编译这个XML文件我们这里要利用到DBUS-BINDING-TOOL这个工具:

dbus-binding-tool --mode=glib-server --prefix=netsetserver netset.xml>netset_server.h

dbus-binding-tool --mode=glib-client --prefix=netsetserver netset.xml>netset_client.h

注意这两句只有MODE是不一样的,所以生成的头文件一个是客户端的一个是服务端的,这里举个NETSET.XML这个文件的示例:

<?xml version="1.0" encoding="UTF-8"?>
<node name="/test/example/server">
 <interface name="test.example.ServerInterface">
  <method name="getmacip">
   <arg name="device" type="s" direction="in"/>
   <arg name="macip" type="ay" direction="out"/>
  </method>
 </interface>
</node>
这里有一个节点node,里面包含一个接口interface,这个接口里头包含一个方法method,方法也就是函数啦,可以理解成这个函数是这样的getmacip(char *device,struct xxx macip),其中device是输入参数,macip是输出参数,注意我这里展示的是比较难的结构体的传递,数据类型是ay,这里涉及到一个用容器存储数据的技巧。

好了现在看看客户端是如何实现的:

#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define MAXIPNUM 1024

typedef struct addr
{
 unsigned char mac[20];
 unsigned char ip[MAXIPNUM*16];
}Addr;

typedef struct testa
{
 int a;
 char b[20];
}Testa;

typedef struct testb
{
 int c;
 Testa t;
}Testb;

static void
lose(const char *str, ...)
{
 va_list args;
 va_start(args, str);
 vfprintf(stderr, str, args);
 fputc('/n', stderr);
 va_end(args);
 exit(1);
}

static void
lose_gerror(const char *prefix, GError *error)
{
 if(error){
  lose("%s: %s", prefix, error->message);
 }
 else{
  lose("%s", prefix);
 }
}

static void
usage()
{
 printf("Usage: client getmacip device./n");
 exit(1);
}

static void
getmacip(DBusGProxy *proxy, char *device)
{
 GError *err=NULL;
 GArray *macip=NULL;
 GArray *arr=NULL;
 Addr *ret;
 Testb *tb;
 if(!dbus_g_proxy_call(proxy, "getmacip", &err,
  G_TYPE_STRING, device,
  G_TYPE_INVALID,
  dbus_g_type_get_collection("GArray",G_TYPE_UCHAR), &macip,
  dbus_g_type_get_collection("GArray",G_TYPE_UCHAR), &arr,
  G_TYPE_INVALID))
  lose_gerror("Failed to getmacip", err);
 else{
  ret = (Addr*)macip->data;
  tb = (Testb*)arr->data;
  printf("The mac is: %s/nThe ip is: %s/n", ret->mac, ret->ip);
  printf("The testb is: %d  %d  %s/n",tb->c, tb->t.a, tb->t.b);
  g_array_free(macip,TRUE);
  g_array_free(arr,TRUE);
 }
}

int main(int argc, char *argv[])
{
 DBusGConnection *bus;
 GError *error=NULL;

 g_type_init();

 printf("Debug............................./n");
 bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
 if(!bus)
  lose_gerror("Countn't connect to session bus", error);

 if(argc == 1){
  usage();
 }
 else if(0 == strcmp(argv[1],"getmacip") && argc == 3){
  DBusGProxy *gmiproxy;
  gmiproxy = dbus_g_proxy_new_for_name(bus, "test.example.Server",
   "/test/example/Server", "test.example.ServerInterface");
  getmacip(gmiproxy, argv[2]);
 }
 else{
  usage();
 }
 exit(0);
}
服务端:

#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <linux/sockios.h>

#define MAXIPNUM 1024
#define MAXINTERFACES 1024

typedef struct Server Server;
typedef struct ServerClass ServerClass;

#define SERVER_TYPE (server_get_type())
GType server_get_type(void);

typedef struct addr
{
 unsigned char mac[20];
 unsigned char ip[MAXIPNUM*16];
}Addr;

typedef struct testa
{
 int a;
 char b[20];
}Testa;

typedef struct testb
{
 int c;
 Testa t;
}Testb;

struct Server
{
 GObject parent;
};

struct ServerClass
{
 GObjectClass parent;
};

enum
{
 LAST_SIGNAL
};

G_DEFINE_TYPE(Server, server, G_TYPE_OBJECT);
gboolean server_getmacip(Server *obj, char *device, GArray **macip, GArray **arr, GError **error);

#include "server-glue.h"

static void
server_init(Server *obj)
{
}

static void
server_class_init(ServerClass *klass)
{
}

static void
lose(const char *str, ...)
{
 va_list args;
 va_start(args, str);
 vfprintf(stderr, str, args);
 fputc('/n', stderr);
 va_end(args);
 exit(1);
}

static void
lose_gerror(const char *prefix, GError *error)
{
 if(error){
  lose("%s: %s", prefix, error->message);
 }
 else{
  lose("%s", prefix);
 }
}

gboolean server_getmacip(Server *obj, char *device, GArray **macip, GArray **arr, GError **error)//这里的macip参数是一个结构体指针
{
       char ips[MAXIPNUM][16];
 char message[MAXIPNUM*16];
 struct ifreq buf[MAXINTERFACES];
 struct ifconf ifc;
 int inter_num = 0;
 int interface = 0;
 int i = 0;
 int sockfd;
 char macaddr[6];
 struct ifreq ifr;
 struct sockaddr_in addr;
 Addr result;
 Testb tb;//如何测试
 memset(&addr,0,sizeof(struct sockaddr_in));
 memset(message,0,MAXIPNUM*16);
 memset(&result,0,sizeof(Addr));
 memset(&tb,0,sizeof(Testb));

 *macip = g_array_new(FALSE,FALSE,sizeof(guint8));//容器
 *arr = g_array_new(FALSE,FALSE,sizeof(guint8));

 //*mac = g_new(char *, 20);
 //*ip = g_new(char *, MAXIPNUM*16);
 //*mac = (char *)g_malloc(sizeof(char)*20);
 //*ip = (char *)g_malloc(sizeof(char)*MAXIPNUM*16);
 if((sockfd = socket(PF_INET,SOCK_DGRAM,0)) == -1)
 {
  fprintf(stderr,"Sock Error: %s/n",strerror(errno));
 }

 memset(&ifr,0,sizeof(ifr));
 strcpy(ifr.ifr_name,device);
 
 if(ioctl(sockfd,SIOCGIFHWADDR,(struct ifreq*)&ifr) == -1)
 {
  fprintf(stderr,"ioctl SIOCGIFHWADDR Error: %s/n",strerror(errno));
  close(sockfd);
 }
 memcpy(macaddr,ifr.ifr_hwaddr.sa_data,6);
 sprintf((char*)result.mac,"%02x:%02x:%02x:%02x:%02x:%02x",(0xff&macaddr[0]),(0xff&macaddr[1]),(0xff&macaddr[2]),(0xff&macaddr[3]),(0xff&macaddr[4]),(0xff&macaddr[5]));

 memset(buf, 0, sizeof(struct ifreq)*MAXINTERFACES);
 ifc.ifc_len = sizeof(struct ifreq)*MAXINTERFACES;
 ifc.ifc_buf = (caddr_t)buf;
 if(!ioctl(sockfd, SIOCGIFCONF, (char *)&ifc))
 {
  inter_num = ifc.ifc_len/sizeof(struct ifreq);
  while(interface < inter_num)
  {
   if(strcmp(buf[interface].ifr_name,device)!=0)
   {
    interface++;
    continue;
   }
   if(ioctl(sockfd,SIOCGIFADDR, (char *)&buf[interface])==-1)
   {
    fprintf(stderr,"ioctl SIOCGIFADDR Error: %s/n",strerror(errno));
    close(sockfd);
   }
   addr = *((struct sockaddr_in*)(&(buf[interface].ifr_addr)));
   strcpy((char*)ips[i],(char*)inet_ntoa(addr.sin_addr));
   sprintf((char*)result.ip, "%s%s", message, (char*)ips[i]);
   sprintf(message, "%s/n", (char*)result.ip);
   i++;
   interface++;
  }
 }
 close(sockfd);
 tb.c = 5;
 tb.t.a = 3;
 strcpy(tb.t.b,"Hello World!");
 g_array_append_vals(*macip, &result, sizeof(Addr));//addr是一个结构体
 g_array_append_vals(*arr, &tb, sizeof(Testb));
 //printf("Success to getmacip/n");
 return TRUE;
}

int main(int argc, char *argv[])
{
 DBusGConnection *bus;
 DBusGProxy *bus_proxy;
 GError *error=NULL;
 GMainLoop *mainloop;
 Server *obj;
 guint request_name_result;

 g_type_init();
 dbus_g_object_type_install_info(SERVER_TYPE, &dbus_glib_server_object_info);

 mainloop = g_main_loop_new(NULL, FALSE);

 bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
 if(!bus)
  lose_gerror("Countn't connect to session bus", error);
 bus_proxy = dbus_g_proxy_new_for_name(bus, "org.freedesktop.DBus",
   "/org/freedesktop/DBus", "org.freedesktop.DBus");
 if(!dbus_g_proxy_call(bus_proxy, "RequestName", &error,
   G_TYPE_STRING, "test.example.Server",
   G_TYPE_UINT, 0,
   G_TYPE_INVALID,
   G_TYPE_UINT, &request_name_result,
   G_TYPE_INVALID))
  lose_gerror("Failed to acquire test.example.Server", error);
 obj = g_object_new(SERVER_TYPE, NULL);
 dbus_g_connection_register_g_object(bus, "/test/example/Server", G_OBJECT(obj));

 g_main_loop_run(mainloop);
 exit(0);
}
编译是这样的:

gcc -Wall netset_server.c -g -o server_netset `pkg-config --libs --cflags dbus-glib-1`

gcc -Wall netset_client.c -g -o client_netset `pkg-config --libs --cflags dbus-glib-1`

注意这里的标点符号哦,很容易出错

对了在运行之前还要还要建立一个DBUS,否则无法通信:

[root@localhost homework]# dbus-launch
DBUS_SESSION_BUS_ADDRESS='unix:abstract=/tmp/dbus-EBop04REqN'
DBUS_SESSION_BUS_PID=1165
[root@localhost homework]# export DBUS_SESSION_BUS_ADDRESS='unix

这样导入一下就OK了,可以测试CS了

上面代码有些是固定的套路,今天不想写了,改天详细的解释一下每一句的意义

抱歉!评论已关闭.