主线程即main reactor负责监听socket,并将accept的连接轮询的交付给其他线程的sub reactor处理,各个sub reactor负责与远端通信
muduo中暴露接口的方式采用的是注册回调函数的形式.并且采用非阻塞的套接字
1、EventLoop类
内部有且仅有一个EventLoop事件循环,这就是主Reactor。这个事件循环主要就是用来监听是否有新的连接到来,
EventLoop类中最主要的就是包含了一个Poller的类对象,这个就是用来实现IO复用的。
内部维护一个Poller,唤醒Channel,触发事件的Channel列表
EpollPoller类内部最主要的就是poll()函数,要求传入超时时间和活跃通道列表。函数内部调用epoll_wait()来返回所有已经就绪的事件个数,然后遍历这些事件,并且为此构建Channel通道,将这些Channel压入到函数传入的活跃通道列表activeChannels中。
2、Channel类
一个fd对应一个channel
仅是对这个fd行为的一个封装。其内部最主要的就是 handleEvent()这个函数,事件到来时EvenLoop会调用handleEvent方法进行处理,内部会根据具体的读写事件来决定使用的回调函数。
EvenLoop与Channel是一对多的关系。
3、TcpConnection类:
TcpConnection相当于是对服务器和客户端之间连接的一种抽象,类中主要是EventLoop、Socket以及Channel这三个类对象指针,在TcpConnection这个类构造的时候,便会将对应的读写回调处理函数注册进Channel中
messageCallback_是类中的一个通用多态函数封装器,可以简单理解为是一个“容器”,用来接收上层传给他的回调函数,也就是说TcpConncetion一般也是作为其他类的成员,接收其传给它的回调函数。
因为Channel是个内部类,所以它的回调函数的注册只能TcpConnection完成
TcpConnection就实现了这一点,它内部维护一个应用层的inputBuffer和outputBuffer保证数据的可靠发送,同时再连接断开时也能保证数据发送完成后再断开
消息接收成功时以接收到的内容和时间为参数调用注册的回调函数供上层使用.
4、Acceptor类
Acceptor负责监听listen_fd,其Channel管理的套接字可读,就意味着有新的连接完成了三次握手到达.因此读事件回调函数注册为accept的一个封装,负责接受新的连接并建立连接套接字(connect_fd).并将 connect_fd 作为参数调用注册的新连接回调函数,供上层使用处理.
newConnectionCallback_ 又是一个用来接收上层回调函数的“容器”。
Accepter是个内部类它属于一个TcpServer, Accepter::newConnectionCallback的实例就是由TcpServer进行注册的
5、TcpServer类
那么传给TcpConnection和Acceptor这两个类的回调函数
在这个函数内部,将会从EventLoop线程池中取得一个新的EventLoop线程,然后构建一个新的TcpConncetion
6、Poller类
Poller类是作为一个基类,会根据环境变量的设置选择是使用epoll还是poll方法,向下有2个派生类,PollPoller和EpollPoller,这也是muduo库中唯一使用面向对象的地方,其余都是基于对象的实现方式。