请注意这是 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 响应服务器的简单流程(本文)函数