請注意這是 libev 而不是 libevent 的文章!
這篇文章主要是使用具體的例子,說明如何使用 libev。網上很多文章都是照抄示例,一點用都沒有……本文將示例的代碼精簡一下,補上說明;你們都懂的部分就不贅述了。須要完整源碼請查看參考資料。html
本文地址:http://www.javashuo.com/article/p-efqpwftt-cq.html程序員
Create tcp echo server using libevsegmentfault
Listen
socketaccept
事件accept
調用read
注意:原文例子中未顯示的是,應當將 fd 設置爲非阻塞的。帶非阻塞設置的代碼以下:服務器
some_init_func() { ... sd = socket (PF_INET, SOCK_STREAM, 0); flags = fcntl (sd, F_GETEL, 0); fcntl (sd, F_SETEL, flags | O_NONBLOCK); bzero (&addr, sizeof(addr)); ... // 設置 Address 和 port bind (sd, (struct sockaddr *)(&addr), sizeof(addr)); ... }
some_init_func() { ... listen (sd, 2); ... }
accept()
的 watchersome_init_func() { ... ev_io_init (&w_accept, accept_cb, sd, EV_READ); ev_io_start (loop, &w_accept); ... }
回調函數以下:socket
static void accept_cb (struct ev_loop *loop, struct ev_io *watcher, int revents) { ... client_sd = accept (watcher->fd, // accept() 調用,接受傳入鏈接 (struct sockaddr *)(&client_addr), &client_len); ... w_client = (struct ev_io *)malloc(sizeof(struct ev_io)); // 爲 read watcher 準備內存 ... ev_io_init (w_client, read_cb, client_sd, EV_READ); // 這裏就只示例 read 事件了。write 事件同理 ev_io_start (loop, w_client); }
read()
的 callbackstatic void read_cb (struct ev_loop *loop, struct ev_io *watcher, int revents) { ... readCount = recv (watcher->fd, buffer, BUFFER_SIZE, 0); // 讀取的方法就視乎程序員的實現啦 send (watcher->fd, buffer, readCount, 0); // 把數據 echo 回去 ... }
原文例子使用的就是recv
/send
,實際上我我的偏心的是read
/write
tcp
ev_loop (loop, 0); // 這裏能夠直接使用 default loop
Libev 官方文檔學習筆記(1)——概述和 ev_loop
Libev 官方文檔學習筆記(2)——watcher 基礎
Libev 官方文檔學習筆記(3)——經常使用 watcher 接口
使用 libev 構建 TCP 響應服務器的簡單流程(本文)函數