2.1 進入剛剛安裝的的zookeeper目錄,而後進入src/c目錄node
2.2 ./configure –-prefix=/home/zookeeper/服務器
2.3 makeapp
2.4 make install異步
而後進入/home/zookeeper下面,能夠看到:async
而後還能夠看獲得各個目錄下面的東西:函數
能夠看獲得,生成的庫裏面既有共享庫,又有靜態庫。spa
創建目錄以下:debug
將剛纔生成的全部頭文件拷貝到common/include下面,將改爲lib下面的libzookeeper_mt.a庫拷貝到common/lib下面。日誌
而後在client目錄下面編寫client.c,代碼以下:code
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <zookeeper.h> #include <zookeeper_log.h> void zktest_watcher_g(zhandle_t* zh, int type, int state, const char* path, void* watcherCtx) { printf("Something happened.\n"); printf("type: %d\n", type); printf("state: %d\n", state); printf("path: %s\n", path); printf("watcherCtx: %s\n", (char *)watcherCtx); } void zktest_dump_stat(const struct Stat *stat) { char tctimes[40]; char tmtimes[40]; time_t tctime; time_t tmtime; if (!stat) { fprintf(stderr,"null\n"); return; } tctime = stat->ctime/1000; tmtime = stat->mtime/1000; ctime_r(&tmtime, tmtimes); ctime_r(&tctime, tctimes); fprintf(stderr, "\tctime = %s\tczxid=%llx\n" "\tmtime=%s\tmzxid=%llx\n" "\tversion=%x\taversion=%x\n" "\tephemeralOwner = %llx\n", tctimes, stat->czxid, tmtimes, stat->mzxid, (unsigned int)stat->version, (unsigned int)stat->aversion, stat->ephemeralOwner); } //當 zoo_aexists 請求完成時會調用該函數 //rc參數爲: ZOK 操做完成;ZNONODE 節點不存在;ZNOAUTH 客戶端沒有權限刪除節點。 void zktest_stat_completion(int rc, const struct Stat *stat, const void *data) { fprintf(stderr, "%s: rc = %d Stat:\n", (char*)data, rc); zktest_dump_stat(stat); } void zktest_void_completion(int rc, const void *data) { fprintf(stderr, "[%s]: rc = %d\n", (char*)(data==0?"null":data), rc); } //當建立節點請求完成時會調用該函數 //rc 參數爲: ZOK 操做完成;ZNONODE 父節點不存在;ZNODEEXISTS 節點已存在;ZNOAUTH 客戶端沒有權限建立節點。ZNOCHILDRENFOREPHEMERALS 臨時節點不能建立子節點 //value 參數即新節點的路徑名 //string_completion_t completion 中 const void *data 參數即爲 zoo_acreate 中的 const void *data。 void zktest_string_completion(int rc, const char *name, const void *data) { fprintf(stderr, "[%s]: rc = %d\n", (char*)(data==0?"null":data), rc); if (!rc) { fprintf(stderr, "\tname = %s\n", name); } } int main(int argc, const char *argv[]) { const char* host = "172.16.186.71:2191"; //若是 30 秒內客戶端沒有鏈接上 Zookeeper 服務則表示鏈接超時。 int timeout = 30000; //設置日誌等級。 zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); //初始化zookeeper句柄(zhandle_t) //第四個參數爲客戶端會話id,客戶端嘗試重連的先前會話的ID,若是不須要重連先前的會話,則設置爲 0 //第五個參數爲當前zk的上下文對象,最後一個參數是預留參數 zhandle_t* zkhandle = zookeeper_init(host, zktest_watcher_g, timeout, 0, "hello zookeeper.", 0); if (zkhandle == NULL) { fprintf(stderr, "Error when connecting to zookeeper servers...\n"); exit(EXIT_FAILURE); } // struct ACL ALL_ACL[] = {{ZOO_PERM_ALL, ZOO_ANYONE_ID_UNSAFE}}; // struct ACL_vector ALL_PERMS = {1, ALL_ACL}; //建立一個znode節點,節點路徑爲"/xyz",保存一個長度爲5,內容爲hello的數據,任何人均可以訪問 //這個一個異步函數,調用以後,直接往下執行,可是此時節點並無真正的建立成功。節點建立成功以後會調用zktest_string_compeltion函數 //最後一個參數是該回調函數,要傳入的參數 int ret = zoo_acreate(zkhandle, "/xyz", "hello", 5, &ZOO_OPEN_ACL_UNSAFE, 0 /* ZOO_SEQUENCE */, zktest_string_completion, "acreate"); if (ret) { fprintf(stderr, "Error %d for %s\n", ret, "acreate"); exit(EXIT_FAILURE); } ret = 0; //第三個參數是監視,若是非 0,則在服務器端設置監視,當節點發生變化時客戶端會獲得通知,即便當前指定的節點不存在也會設置監視,這樣該節點被建立時,客戶端也能夠獲得通知。 ret = zoo_aexists(zkhandle, "/xyz", 1, zktest_stat_completion, "aexists"); if (ret) { fprintf(stderr, "Error %d for %s\n", ret, "aexists"); exit(EXIT_FAILURE); } ret = 0; // Wait for asynchronous zookeeper call done. getchar(); //第三個參數:指望的節點版本號,若是真實的版本號與指望的版本號不一樣則 zoo_delete() 調用失敗,-1 表示不不檢查版本號。 ret = zoo_adelete(zkhandle, "/xyz", -1, zktest_void_completion, "adelete"); if (ret) { fprintf(stderr, "Error %d for %s\n", ret, "adelete"); exit(EXIT_FAILURE); } // Wait for asynchronous zookeeper call done. getchar(); zookeeper_close(zkhandle); return 0; }
而後編寫makefile 以下
LIB_DIR=../common/lib CC=gcc RM=rm -rf CFLAGS=-c -Wall -DTHREAD -I../common/include client:client.o $(CC) $^ -lzookeeper_mt -lpthread -lm -L${LIB_DIR} -o $@ client.o:./client.c $(CC) $(CFLAGS) $^ clean: $(RM) client *.o
最後的運行結果以下:
至此,該程序寫完了,祝玩的愉快!