muduo源码分析--Reactor模式的在muduo中的使用(二)
发布时间:2020-12-15 04:53:59 所属栏目:百科 来源:网络整理
导读:一. TcpServer类: 管理所有的TCP客户连接,TcpServer供用户直接使用,生命期由用户直接控制。用户只需设置好相应的回调函数(如消息处理messageCallback)然后TcpServer::start()即可。 主要数据成员: boost::scoped_ptrAccepter acceptor_; 用来接受连接
一. TcpServer类:管理所有的TCP客户连接,TcpServer供用户直接使用,生命期由用户直接控制。用户只需设置好相应的回调函数(如消息处理messageCallback)然后TcpServer::start()即可。 主要数据成员:boost::scoped_ptr<Accepter> acceptor_; 用来接受连接 std::map<string,TcpConnectionPtr> connections_; 用来存储所有连接 connectonCallback_,messageCallback_,writeCompleteCallback_,用来接受用户注册的回调函数 EventLoop* loop; 接受连接的事件循环 主要功能函数:set*Callbak() 注册用户回调函数 newconnection() 需要在构造函数内将其注册给Acceptor,当Acceptor接受一个连接之后回调该函数。在本函数内部新建一个connection对象,并将 *Callback_注册给新建的 Connection 对象。最后,从线程池取出一个线程做I/O线程,在该I/O线程的 EventLoop 的 runInLoop() 中传入 TcpConnection::connectEstablished(). 因为必然不在一个线程中,在runInLoop()中调用EventLoop::quueInLoop(),将TcpConnection::connectEstablished()加入pendingFunctors. 二. Acceptor类:负责监听连接请求,接收连接并将新的连接返回给TcpServer。 Acceptor主要是供TcpServer使用的,其生命期由后者控制。一个Acceptor相当于持有服务端的一个listenning socket描述符,该socket可以accept多个TCP客户连接,。 主要数据成员:EventLoop* loop_; Socket acceptSocket_;封装了socket等,用来监听 Channel acceptChannel_;Acceptor通过Channel向Poller注册事件,EventLoop通过Channel分发回调Acceptor相应的事件处理函数。 boost::function<void(sockfd,InetAddress&)>NewConnectionCallback_,连接请求接收之后,通过其回调TcpServer::newconnection(). 主要功能函数:listen(),调用Socket::listen()开始监听,同时,调用Channel::enableReading()向Poller注册可读事件,有数据可读代表新来了连接请求。 handleRead(),在构造函数中将其注册给Channel::readCallback_。当Poller发现属于Acceptor的Channel的可读事件时,在EventLoop中会驱动Channel::handleEvent()-->Channel::handleEventWithGuard()进行事件分发,调用readCallback回调 Acceptor::handlRead(),在其内调用Socekt::accept(),再回调TcpServer::newconnection(),将新连接的sockfd传回给TcpServer。 服务端监听及接受连接的流程:向Poller注册监听事件的主线调用流程,TcpServer::start()-->EventLoop::runInLoop(Acceptor::listen())-->Channel::enableReading()-->Channel::update(this)-->EventLoop::updateChannel(Channel*)-->Poller::updateChannel(Channel*) 接受连接,当Poller::poll()发现有事件就绪,通过 Poller::fillActiveChannel() 将就绪事件对应的 Channel 加入 ActiveChannelList, EventLoop::loop()-->Poller::poll()-->Poller::fillActiveChannel(),loop()-->Channel::handleEvent()->Acceptor::handleRead()->TcpServer::newConnection()->EventLoop::runInLoop(bind(&TcpConnection::connectEstablished))->EventLoop::queueInLoop()->EventLoop::loop()->EventLoop::doPendingFunctors()->TcpConnection::connectEstablished()。 三. Connection类:用于管理一个具体的TCP客户连接,完成用户指定的连接回调connectionCallback。 TcpConnection构造时接收参数有TCP连接的描述符sockfd,服务端地址localAddr,客户端地址peerAddr,并通过Socket封装sockfd。且采用Channel管理该sockfd, 主要数据成员:enum StateE { kDisconnected,kConnecting,kConnected,kDisconnecting };分别表示已断开,正在连接,已连接,正在断开。 scoped_ptr<Socket> socket_;封装该连接的socket scoped_ptr<Channel> channel_;连接可以通过该channel向Poller注册该连接的读写等事件。连接还要向Channel注册TcpConection的可读/可写/关闭/出错系列回调函数,用于Poller返回就绪事件后Channel::handleEvent()执行相应事件的回调。 boost::function<void()> **Callback_,在TcpServer::newconnection()中创建TcpConnection时,就会将TcpServer中的各种处理函数注册给相应的 TcpConnection::*Callback_ 。 Buffer inputBuffer_,outputBuffer_。输入输出的缓冲。 主要功能函数:handle{Read(),Write(),Close(),Error()},处理连接的各种事件,会由Channel::handleEvent()根据Poller返回的具体就绪事件分发调用相应的TcpConnection::handle**(). connectEstablished(),设置连接的状态为kConnected,将channel_进行绑定,调用channel::enableReading()向Poller注册读事件,最后回调connectionCallback_会回调TcpServer中相应的回调函数,一般会在TcpServer中继续回调用户传进来的回调函数。 send(),sendInLoop(),send()有几个重载都是进行发生数据,send()-->sendInLoop(),后者中检测输出buffer中没有数据排队就直接写,如果没有写完,或者outbuffer中有数据排队则将数据追加到outbuffer中,然后调用channel::enableWriting()向Poller注册写事件。 TcpConnection::setTcpNoDelay()->socketopt(..,TCP_NODELAY..)来关闭Nagle算法。 发送数据流程:TcpConnection::send(string& message)->EventLoop::runInLoop(bind(&TcpConnection::sendInLoop(string& message))->EventLoop::doPendingFunctors()->TcpConnection::sendInLoop(string& message)保证消息发送的线程安全,后者通过write系统调用发送消息。 当Poller返回一个连接的可写或者可读就绪事件时,回调过程类似Acceptor的连接接受过程。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- vb6 – OleControl实例化为错误类型 – 仅在Reg Free COM中
- c – 在#define中使用0x1是什么意思?
- 对于一台机器上的结构化数据,NoSQL对RDBMS有什么实际的优势
- c# – 如何在datagridview中的列中显示文本框中已选中复选框
- React-Native进阶_4.底部标签栏TabBar
- Oracle12c DataGuard Far Sync的配置和使用简介(上)
- AOP基础知识及AOP切面编程之注释方法、xml配置方法
- Swift spritekit设置了userdata
- 学习VB.NET 变量命名三原则
- Linux系统上配置Nginx+Ruby on Rails+MySQL超攻略