Contents
  1. 1. 编译
  2. 2. 使用
  3. 3. 包装
  4. 4. 应用
  5. 5. 优化
  6. 6. 总结

决定找些工具过来方便自己做些个人开发,这里是 libevent

libevent也算是个比较著名的C网络库了,在libev出现之前,基本上每3个需要进行网络功能开发的人就有1个会选它。

它在windows上采用IOCP收发消息、Linux下使用epoll,都是一般情况下人们会去选择的网络模型。它对一些网络异常、IO事件进行了封装,向用户提供一族比较简单的接口和参数设置,使用户无需精通网络编程也能写出大致靠谱的网络应用。

除此之外它还提供了定时器、rpc框架、http server、dns解析等功能。

编译

libevent使用起来还是非常方便的,到官网下载到最新的stable包之后解压之后进去,windows下的编译方法是:

>nmake /f Makefile.nmake

控制台找不到nmake的话,就试试用vs提供的控制台cd到libevent的目录下再敲。

使用

然后建一个vs空项目,开始使用libevent编写一个echo server。

因为还不熟悉libevent的用法,最快速搭建应用的方法就是从libevent目录下的sample文件夹下找个最简单的栗子把代码cp到工程文件里来。

然后对vs工程进行配置,加上libevent的include目录、lib目录,再在链接器的input下加上之前编译出来的libevent.lib,然后开始build。

build过程中发现缺少文件,查看出错的地方发现是这样:

#ifndef WIN32
#include <netinet/in.h>
# ifdef _XOPEN_SOURCE_EXTENDED
#  include <arpa/inet.h>
# endif
#include <sys/socket.h>
#endif

很显然是编译器搞错平台了,因为我没有包含windows.h,所以进行宏判定的时候认为不是win32的环境,同样在工程C++配置的preprocessor里补上WIN32再build。

…发现还是少个文件,event2/event-config.h,这个问题没看到官方文档上有写,不过其实这样正经的解决思路是这样:

C++ include path那里把libevent目录下面有个叫WIN32-Code的目录加进来

然后再build…发现链接出错,基本上都是些wsa开头的,于是意识到是没有链接到windows系统提供的网络库导致,继续在Linker的input中加上ws2_32.lib。

再build…终于,一个新鲜的网络应用出炉了。

包装

因为libevent是个C语言库,为了自己使用的时候能够对代码风格作下统一,需要进行C++ Style的封装。

这可能用好多种设计,我自己一般是把它做成一个ConnMgr的形式,或者往Reactor靠拢。
其实libevent本身就有比较明显的Reactor的味道,封装成C++版Reactor也是比较自然想到的事情。

另外在libevent中,clientsock是以bufferevent作为载体的,开发的时候概念上也不是很直观,所以客户端链接的地方自己把它定义成Pipe,接收消息转到OnRecv中处理,对外提供Send接口。

应用

到这里差不多就能把libevent真正拿来做开发了,但是真正去考虑的时候发现还有网络数据没去处理,这个暂时不清楚libevent有没有提供序列化数据的工具,不过这个问题现在一般流行用protobuf解决的。

protobuf和libevent是比较容易整合的,只需在收发的地方做下编码解码就可以了。

这样网络层的基本工具就差不多有了,唯一还缺的就是一套漂亮的消息处理函数,这个问题我知道的C++上一般是语法支持的情况下尽量封装的看上去像RPC调用一样,具体的实现改天再写。

前面也说了libevent也是有提供RPC框架的,不过我搜了下基本没人谈论这个问题…网上栗子不好找,SO上唯一一条回答的内容是推荐用libev+protobuf…

看这里:http://stackoverflow.com/questions/18757293/does-anyone-used-rpc-framework-inside-libevent

所以rpc的这个问题只好改天再研究了。

优化

因为才刚开始接触,架构/算法层面上的优化不好讲,不过收消息的地方目前来看是可以稍作优化的。

官方的demo里从inbuffer里读数据需要进行一次cp操作,可以考虑一下能否省掉这个步骤直接去读inbuffer里的数据。

另外呢,拒libev透露,其设计的初衷就是为了“improve libevent”,关于libevent的问题也可以侧面从libev的介绍里作下了解。

其他优化问题的讨论需要等有了深入了解之后再来补充。

总结

总体上感觉还是比较好用的,从下载到完成测试没有花太多时间,接口也比较清晰,稍微熟悉命名规则之后,配合vs的代码提示经常可以脱离文档栗子写一些代码。

这相比自己没完没了的翻UNP记各种可能出现的状况和错误代码还要去处理各种异常信号绝对是个福音了。

不过对于还有比较重要的一点是,多线程情况下的处理问题,能不能一样保持效率和清爽的逻辑。这个也得来日再来学习啦。

我把写的一些功能测试代码放到github上了,方便以后回顾用。

https://github.com/ooomceg/examples

客户端的测试工具用的是netcat,顺便推荐一下,很小很强大。

nc -nvv 127.0.0.1 9995
Contents
  1. 1. 编译
  2. 2. 使用
  3. 3. 包装
  4. 4. 应用
  5. 5. 优化
  6. 6. 总结