tcp服务器同时响应,使用 libev 构建 TCP 响应服务器(echo server)的简单流程

请注意这是 libev 而不是 libevent 的文章!

这篇文章主要是使用具体的例子,说明如何使用 libev。网上不少文章都是照抄示例,一点用都没有……本文将示例的代码精简一下,补上说明;大家都懂的部分就不赘述了。需要完整源码请查看参考资料。

Reference

基本流程

创建 socket,绑定 socket 地址

Listen socket

创建一个 watcher,用来承载accept事件

写一个 callback 用来做实际的accept调用

创建并初始化一个 watcher 用来从 client 中读取请求

写一个 callback 用来read

启动 event loop

创建 socket 并绑定 address

注意:原文例子中未显示的是,应当将 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()的 watcher

some_init_func()

{

...

ev_io_init (&w_accept, accept_cb, sd, EV_READ);

ev_io_start (loop, &w_accept);

...

}

回调函数如下:

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()的 callback

static 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

启动 event loop

ev_loop (loop, 0); // 这里可以直接使用 default loop

系列篇

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值