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);