一、安裝libevent
官網:http://libevent.org/
選擇最新版本下載,我選擇的是libevent-2.0.22-stable.tar.gz,然后安裝README文件中描述的方法編譯、安裝即可。
./configure make make verify # 可選操作 make install
二、使用libevent
示例1:回顯服務器
/******************************************************************************* * File Name : echo.c * Author : zjw * Email : emp3XzA3MjJAMTYzLmNvbQo= (base64 encode) * Create Time : 2015年07月14日 星期二 09時05分37秒 *******************************************************************************/ #include <event.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #define SERVER_PORT 8080 int debug = 0; struct client { int fd; struct bufferevent *buf_ev; }; int setnonblock(int fd) { int flags; flags = fcntl(fd, F_GETFL); flags |= O_NONBLOCK; fcntl(fd, F_SETFL, flags); } void buf_read_callback(struct bufferevent *incoming, void *arg) { struct evbuffer *evreturn; char *req; req = evbuffer_readline(incoming->input); if (req == NULL) { return ; } evreturn = evbuffer_new(); evbuffer_add_printf(evreturn, "You said: %s\n", req); bufferevent_write_buffer(incoming, evreturn); evbuffer_free(evreturn); free(req); } void buf_write_callback(struct bufferevent *bev, void *arg) { } void buf_error_callback(struct bufferevent *bev, short what, void *arg) { struct client *client = (struct client*)arg; bufferevent_free(client->buf_ev); close(client->fd); free(client); } void accept_callback(int fd, short ev, void *arg) { int client_fd; struct sockaddr_in client_addr; socklen_t client_len = sizeof(client_addr); struct client *client; client_fd = accept(fd, (struct sockaddr*)&client_addr, &client_len); if (client_fd < 0) { perror("Client: accept() failed"); return ; } setnonblock(client_fd); client = calloc(1, sizeof(*client)); if (client == NULL) { perror("1 malloc failed"); } client->fd = client_fd; client->buf_ev = bufferevent_new(client_fd, buf_read_callback, buf_write_callback, buf_error_callback, client); bufferevent_enable(client->buf_ev, EV_READ); } int main(int argc, char **argv) { int socketlisten; struct sockaddr_in addresslisten; struct event accept_event; int reuse = 1; event_init(); socketlisten = socket(AF_INET, SOCK_STREAM, 0); if (socketlisten < 0) { fprintf(stderr, "Failed to create listen socket"); return 1; } memset(&addresslisten, 0, sizeof(addresslisten)); addresslisten.sin_family = AF_INET; addresslisten.sin_addr.s_addr = INADDR_ANY; addresslisten.sin_port = htons(SERVER_PORT); if (bind(socketlisten, (struct sockaddr*)&addresslisten, sizeof(addresslisten)) < 0) { fprintf(stderr, "Failed to bind"); return 1; } if (listen(socketlisten, 5) < 0) { fprintf(stderr, "Failed to listen to socket"); return 1; } setsockopt(socketlisten, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); setnonblock(socketlisten); event_set(&accept_event, socketlisten, EV_READ | EV_PERSIST, accept_callback, NULL); event_add(&accept_event, NULL); event_dispatch(); close(socketlisten); return 0; }
編譯並運行該回顯服務器:
gcc -o echo ./echo.c -levent ./echo
但是在運行的時候提示找不到動態鏈接庫,那么肯定是庫放的路徑,鏈接器找不到,所以翻看執行make install命令時把庫安裝在什么地方了。
如果再./configure時不指定--prefix=/usr,則默認會安裝在/usr/local/lib路徑下。所以需要創建軟鏈接。
我的是64位系統,所以軟鏈接應該創建在/usr/lib64目錄下: n -s /usr/local/lib/libevent-2.0.so.5 /usr/lib64/libevent-2.0.so.5
然后再執行: ./echo 運行之后不會有提示,為了測試,可以保持該終端開着,另開一個終端,使用telnet來測試一下。
執行: telnet localhost 8080
示例2:定時器
/******************************************************************************* * File Name : timer.c * Author : zjw * Email : emp3XzA3MjJAMTYzLmNvbQo= (base64 encode) * Create Time : 2015年07月14日 星期二 10時00分08秒 *******************************************************************************/ #include <stdio.h> #include <iostream> #include <event.h> using namespace std; // 定時器事件回調函數 void OnTime(int sock, short event, void *arg) { cout << "Game Over!" << endl; struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; // 重新添加定時事件(定時事件觸發后默認自動刪除) event_add((struct event*)arg, &tv); } int main() { // 初始化 event_init(); struct event evTimer; // 設置定時事件 evtimer_set(&evTimer, OnTime, &evTimer); struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; // 添加定時事件 event_add(&evTimer, &tv); // 事件循環 event_dispatch(); return 0; }
編譯並運行該定時器: g++ -o timer ./timer.cpp -levent
運行結果:
參考:
http://www.ibm.com/developerworks/cn/aix/library/au-libev/
http://www.open-open.com/lib/view/open1386510630330.html