基于libqb的IPC通讯

1.libqb的基本说明:

libqb库主要目的是提供高性能C/S可重用的特性,它提供了高性能日志记录、跟踪、ipc通讯和poll等。

libqb库注重api的实现,高度调整最大的客户机/服务器应用程序的性能。

2.libqb源码下载:

git clone git://github.com/ClusterLabs/libqb.git

3.在linux环境下的编译:

libqb的实现考虑到了跨平台的使用,所以开发基于glib,Makefile也是使用了automake及libtool等自动生成Makefile。

1)环境配置:

安装autoconf:

yum install autoconf

安装automake:

yum install automake

安装libtool:

yum install libtool

2)生成Makefile

执行Makefile生成脚本: 

./autogen.sh && ./configure

即生成编译Makefile

3)编译安装:

make && make install

编译生成动态库libqb.so,并将相关头文件安装在/usr/include目录下

4.使用libqb编写进程通讯server端:

1)包含libqb相关头文件:

#include <signal.h>
#include <qb/qbdefs.h>
#include <qb/qbutil.h>
#include <qb/qblog.h>
#include <qb/qbloop.h>
#include <qb/qbipcs.h>
#include "os_base.h"

2) 先定义好需要使用的消息结构:

struct srv_req {
struct qb_ipc_request_header hdr;
  char message[256];
};

3) 设置IPC通讯类型,注册server端事件处理函数:

enum qb_ipc_type ipc_type = QB_IPC_NATIVE;
struct qb_ipcs_service_handlers sh = {
  .connection_accept = connection_accept_fn,
  .connection_created = connection_created_fn,
  .msg_process = msg_process_fn,
  .connection_destroyed = connection_destroyed_fn,
  .connection_closed = connection_closed_fn,
};
struct qb_ipcs_poll_handlers ph = {
  .job_add = my_job_add,
  .dispatch_add = srv_dispatch_add,
  .dispatch_mod = srv_dispatch_mod,
  .dispatch_del = srv_dispatch_del,
};

server跑起来后,接收到client发送过来的数据都会触发qb_ipcs_service_handlers结构中的

.msg_proscess回调函数,例如上面注册好的函数: 

void msg_process_fn(qb_ipcs_connection_t * c, void *data, size_t size)
{
    struct srv_req *req_pt;
    hdr = (struct qb_ipc_request_header *)data;
    if (hdr->id == (QB_IPC_MSG_USER_START + 1))
    return 0; req_pt = (struct srv_req *)data; printf( "msg received (id:%d, size:%d, data:%s)", req_pt->hdr.id, req_pt->hdr.size, req_pt->message); }

在 msg_process_fn回调函数中,可以进行client发过来的消息处理。

4)使用注册好的handle创建IPC server,并运行,此处以"testserver"命名server:

static qb_loop_t *bms_loop;
static qb_ipcs_service_t *s1;
s1 = qb_ipcs_create("testserver", 0, ipc_type, &sh);
if (s1 == 0) {
  qb_perror(LOG_ERR, "qb_ipcs_create");
  exit(1);
}
/* This forces the clients to use a minimum buffer size */
qb_ipcs_enforce_buffer_size(s1, ONE_MEG);
bms_loop = qb_loop_create();
qb_ipcs_poll_handlers_set(s1, &ph);
rc = qb_ipcs_run(s1);
if (rc != 0) {
  errno = -rc;
  qb_perror(LOG_ERR, "qb_ipcs_run");
  exit(1);
}
qb_loop_run(bms_loop);

5.有了IPC server端,client端只需要连接上命名好的serve,即可开始通讯收发消息:

首先定义一个connect变量:qb_ipcc_connection_t *conn;

然后定义自己的消息结构体:

struct srv_req {
    struct qb_ipc_request_header hdr;
    char message[256];
};

struct srv_res {
    struct qb_ipc_response_header hdr;
    char message[256];
};

connect server成功后,即可send 数据给server(testserver)端:

conn = qb_ipcc_connect("testserver", 0);
if (conn == NULL) {
  perror("qb_ipcc_connect");
  exit(1);
}

例如,可以调用send api:qb_ipcc_send发送数据,并处理接收返回数据:

struct srv_req req;
struct srv_res res;
char *newline;
int32_t rc;
int32_t send_ten_events;
while (1) {
  printf("SEND (q or Q to quit) : ");
  if (fgets(req.message, 256, stdin) == NULL)
    continue;
  newline = strrchr(req.message, '\n');
  if (newline) {
    *newline = '\0';
  }
    if (strcasecmp(req.message, "q") == 0) {
    break;
  } 
  else {     req.hdr.id = QB_IPC_MSG_USER_START + 3;     req.hdr.size = sizeof(struct my_req);     rc = qb_ipcc_send(conn, &req, req.hdr.size);     if (rc < 0) {       perror("qb_ipcc_send");       exit(0);     }
  } }

client send结束后,释放qb_ipcc_connection_t:

qb_ipcc_disconnect(conn);
posted @ 2014-07-05 12:21  andyzhekun  阅读(2595)  评论(0编辑  收藏  举报