• muduo源代码分析--Reactor在模型muduo使用(两)


    一. 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,client地址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连接验收过程。

  • 相关阅读:
    1.从Node.js链接到MongoDB
    2.mongoDB add user in v3.0 问题的解决(Property 'addUser' of object admin is not a func)
    汇编——模拟试卷二
    汇编——模拟试卷一
    汇编语言——数据处理的两个基本问题(处理的数据在什么地方 要处理的数据有多长)
    汇编语言——更灵活的定位内存地址的方法
    汇编语言——包含多个段的程序
    汇编语言——[bx]和loop指令
    汇编语言——汇编程序从写出到最终执行的过程
    汇编语言——编译器
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4825181.html
Copyright © 2020-2023  润新知