基於libqb的IPC通信

1.libqb的基本說明:linux

libqb庫主要目的是提供高性能C/S可重用的特性,它提供了高性能日誌記錄、跟蹤、ipc通信和poll等。git

libqb庫注重api的實現,高度調整最大的客戶機/服務器應用程序的性能。github

2.libqb源碼下載:api

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

3.在linux環境下的編譯:服務器

libqb的實現考慮到了跨平臺的使用,因此開發基於glib,Makefile也是使用了automake及libtool等自動生成Makefile。函數

1)環境配置:oop

安裝autoconf:性能

yum install autoconf

安裝automake:ui

yum install automake

安裝libtool:spa

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);
相關文章
相關標籤/搜索