enet网络库简单理解

首先声明该enet网络库已经是很老的版本了。

1. 语言c++

2. 环境:centos 6.0, g++72

本章主要介绍enet网络库的实现原理,以及各个组件的功能以及介绍。

介绍:enet网络库是一个利用epoll实现的支持tcp,udp,http等不同协议(可自由扩展)的高并发网络库。

组件:EpollSocketEvent:封装了epoll,暴露接口有:

    1. addEvent:该函数有两个操作:

        1. 将Socket对象中包含的socketHandle使用epoll_ctl加入到epoll的集合中;

        2. 给该sockfd对应的epoll_event结构体的data.ptr赋值成Socket唯一对应的iocomponent指针。

    2. removeEvent:同上,删除从epoll集合中删除该Socket对象;

    3. getEvents:利用epoll_wait将有io请求的事件过滤出来,因为addEvent的时候给每个epoll_event对象的data.ptr域都赋了iocomponent的指针,所以外部就能访问到该对象;

                                                    

上文中提到了iocomponent对象,他的含义如下:

组件:iocomponent:目的是将该类设置为epoll回调后让不同的io组件可以有不同的处理方式(个人觉得reactor模型的精髓和重点就在这里),每一个组件包含一个句柄,在网络例子下,每一个iocomponent都包含了一个socket文件描述符,该类为基类,包含了handleReadEvent,handleWriteEvent, handleErrorEvent等函数,外部的tcpacceptor,tcpcomponent都继承iocomponent类,然后去实现自己的上述函数,用上述组件EpollSocketEvent去addEvent的时候,带入相应的iocomponent即可,EpollSocketEvent用epoll_wait得到的events里的epoll_event.data.ptr就是相应的iocomponent。

组件:Socket:一个socket对象代表着一个socket描述符和上述的iocomponent组件是相互包含和一一对应关系。

组件:Transporter:是所有连接的管理者,包含了EpollSocketEvent成员对象,Transporter启动了两个线程(分别是读写线程和超时线程),当然还有用一个线程判断的模式,在实际的生产中我们并没有用到单线程模式,所以这里就不详细做介绍。读写线程是通过EpollSocketEvent对象的getEvents函数获得所有有相应的事件,然后拿到事件对应的iocomponent基类指针,然后判断epoll中获取到的事件的状态(错误(EPOLLERR | ERPOLLHUP),读事件(EPOLLIN),写事件(EPOLLOUT))来调用iocomponent对应的函数,如图所示:

                                   

组件:Tcpcomponent:因为我们是用tcp做的通信,所以tcpcomponent是我们主要使用的组件。一个tcpcomponent对应一个连接(connect对象),每个Tcpcomponent都对应一个connect对象,connect类也是基类,该类含有派生类TcpConnect。connect对象对应了一个socket连接,是由acceptor返回的。数据的读写都通过tcpcomponent。

      1.首先客户端会调用Request函数将packet数据通过Connect对象的postPacket接口发送给服务端,postPacket是个异步接口,该函数需要4个参数,其中第二个参数是指定的回调函数。该函数发送数据的同时,将packet、channel、回调函数绑定后放入channelPool中,并加入outputQueue中,该队列的作用是过滤掉timeout的请求。

      2.服务端计算完成后会给客户端回包,回包后由客户端的transporter中的epoll对象监听到,会调用ioc的handleReadEvent函数,经过一些列调用后会调用到TCPConnect的readData函数,该函数解析到packet后调用connect的handlePacket函数处理收到的packet。

     3. 首先从1中的channelpool中找出相应的channel,再根据channel中存储的handlePacket处理回包即可。

组件:Tcpacceptor:该组件的目的是有新连接来了,将该链接封装成Connect对象,然后将该对象加入epoll监听的描述符内。该组件主要用于服务端,同样在transporter里注册后利用epoll的回调函数找到tcpacceptor然后调用_serverAdapter的handlePacket。不过不同的点在于,服务端接到数据后处理完成立刻就能发送,不用在经过epoll。

看图吧,调用关系太乱了,不过图也画的乱,不会画图,天生硬伤。

                                     

总结:

    以上就是enet里主要的组件和客户端连接服务端的图,其实没有过多的描述服务端,其实服务端就是一个反应堆模型,我写了一个小例子,关于反应堆模型的,也不是很难理解,添加在附件里了。

大概就是这么个关系。也不想写了。以后有机会在补充吧,再见了esearch,再见了58,再见了这篇文章。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值