暂且,只偏向于游戏服务器。
前后半年多,从一个雏形到现在基本上功能够用。
性能上也经过仔细雕琢,当然肯定有更好的优化方案,暂时未想到,若你有好的建议,并愿意探讨,请联系我,谢谢!。
项目地址:https://github.com/lcinx/lxnet
它是什么:
是一个tcp的非通用网络库,在考虑空间占用、性能、功能性的基础上,结合项目需求而产生的。
压缩,加密在网络线程里执行。
适用平台:
Windows、Linux、Mac OS X
适用场合、范围:
适合于这样的应用:
需要在某一个特定的线程中处理若干个连接的网络消息包,在此线程(但不限于)中进行回馈数据包。 --- 比如 逻辑处理为单线程的游戏服务器。
反例:web服务器这样的echo服务(其可多线程逻辑 --- 故... ), 其为收到请求,返回,类似这样的应用不推荐使用。
特别注意的:
a). 对于一个连接的实体---socketer对象,getmsg方法同时只能在一个线程中调用,源于其缓冲实现。同样,sendmsg也只能同时在一个线程中调用,否则,,,
b). 当accept一个连接后,若未投递接收数据操作(调用 checkrecv类似的方法,不用担心重复投递操作问题。),则不会收到消息包的。
c). sendmsg仅仅是把数据压入缓冲中而已,若未投递发送数据操作(调用 checksend类似的方法不用担心重复投递操作问题。),则不会真正的发送。
d). 关于界限(遇过缓冲撑爆吗?)。 对于服务器而言,防止恶意等比较重要, 此处提供接收界限 --- 接收到的数据达到界限时,不在进行接收,若下次可接收时,也只有用户去投递接收。发送的界限 --- 若客户端一直不接收,而服务器的“推”导致给客户端发送很多数据时,达到界限时,会断开此连接。
e). 关于加密。提供的默认加密/解密就是简单的异或运算而已。 支持对某个连接设置自定加密/解密函数,可附加加密/解密逻辑数据,来实现类似wow那样的加密。 可参考arcemu源码。
对某个连接开启加密或解密时, 切记对端开启相反的。
f). 关于压缩。采用quicklz压缩库(关于它的性能测试可以参考其官方)。 理想的使用状况为 --- 导致聚集压缩。
如:
一帧结束时在调用checksend类似方法(不了解什么是帧的,可以理解为程序中的那个死循环一次为一帧,暂且如此理解)。 此时为最优聚集压缩, 若每次sendmsg后,调用下checksend,那么。。。聚集压缩的优势就不会那么明显的(也可认为压缩比没那么高,对于较少的数据,压缩比始终是 不合算的,聚集压缩可减少压缩库api调用次数,从而降低cpu开销,并可以提高压缩比 --- 相对于压缩较少的数据)。
若开启压缩时,请注意net_init 中的buf参数,不论用的smallbuf还是bigbuf, 客户端的对应的要和服务器的相匹配。 想象下,解压缩的时候,用于解压缩的缓冲容纳不下?(此缓冲大小外部无接口设置,它大小是参考bigbuf, smallbuf中的较大值,再加上一个预留值)。
启用压缩,也切记配对。
g). bigbuf与smallbuf, 不代表bigbuf一定要大于smallbuf, 无此检测。
对于服务器间通讯,buf大点好,可以设置256KB, 对于客户端与服务器间,一个buf 8K 或 16K 或 32K(根据数据量来衡量), 粒度越小,分配频率越高,开销越大。
h). buf管理采用块链,无任何空间浪费。
如何扩展消息包结构:
继承 msgbase.h 文件中的 Msg 即可。
说明(续): 这样一种情况下的用法:
A线程处理逻辑,B线程处理 数据库操作,数据库操作完成时,需要通过网络发送出去;为了避免在不同线程中调用sendmsg(A线程可能还发送ping消息。), 一个可行的方案是:使用任务队列,A线程里压入任务,B线程获取任务,数据库操作完成后,再把任务结果压入队列;在A线程中处理任务 --- 也就是发送数据。