对libuv的C++封装

uv-cpp是一个基于libuv的C++封装网络库,基于本人实际项目需求开发并使用。接口较为简单易用,并对libuv一些特性做了扩展及优化。压测结果稳定、高效。未发现内存泄漏及崩溃相关bug。

  • 为什么需要封装libuv

截至目前,C++没有标准网络库,常见的有ACE和boost.asio。ACE较为庞大臃肿,封装复杂,个人不推荐。boost.asio是boost库的一部分,需要依赖boost的部分实现,使用asio需要在项目引入较为庞大的boost库。而C语言的网络库主要有libevent、libev及libuv。libuv是nodejs的底层,较为成熟。所以如果在项目需要一套轻量级,且没有太多依赖的网络组件,最好的办法,还是自己封装一套。

  • uv-cpp功能简介

1.实现了C++功能的回调
首先libuv是一个C语言库,意味着回调函数是C语言的回调,所以直接使用libuv网络消息回调,相关对象必须是全局的或者static对象,这是令人难以容忍的。这里通过libuv的用户数据功能实现了C++风格的回调,回调函数可以类成员函数,或者lambda。同时封装了TcpServer及TcpClient等类,简化编程。

2.对线程安全做了优化
libuv是一个非线程安全的库,跨线程发送数据数不允许的。uv-cpp中实现了线程安全的跨线程write数据操作。基于libuv的async异步机制实现,同时在跨线程调用时候会检查当前调用线程,如果在该loop线程中则直接发送,减少了不必要的性能损耗。实现如下:

void uv::EventLoop::runInThisLoop(const std::function& func)
{
    if (nullptr == func)
        return;

    if (isRunInLoopThread())
    {
        func();
        return;
    }
    async_->runInThisLoop(func);
}

同时libuv的aysnc接口存在多次调用只执行一次的可能(特性),比如有些操作需要在回调里面释放数据,这样就会内存泄漏。uv-cpp中的Async类优化这个问题,确保每次调用一定会被执行。

3.实现了定时器及时间轮
对libuv定时器做了一层封装,并实现了一个时间复杂度O(1)的时间轮,用于检测心跳超时。

4.实现整包发送/接受协议机制
实现了ListBuffer和CycleBuffe两种缓存机制,用于解决TCP的粘包及残包。数据会重新组成完整的包数据用于读取。性能测试显示CycleBuffe会损失20%~30%的性能。

5日志接口
uv-cpp没有实现日志功能,但是保留了接口,可以注册/绑定到自定义日志库中使用。

  • uv-cpp的使用

详见example文件夹:https://github.com/wlgq2/uv-c...

你可能感兴趣的:(tcp-ip,网络,c++)