muduo的Tcpserver类源码分析

 

TcpServer是创建一个服务器的开始。

TcpServer class的功能是管理accept(2)获得的TcpConnection。TcpServer是供用户直接使用的,生命期由用户控制

TcpServer新建连接的相关函数调用顺序如图下所示:

其中Channel::handleEvent()的触发条件是listening socket可读,表明有新连接到达。TcpServer会为新连接创建对应的TcpConnection对象。

TcpServer class的接口和属性如下图所示:

主要讲下TcpServer主要的几个函数

首先讲下TcpServer的构造函数:

TcpServer::TcpServer(EventLoop* loop,
                     const InetAddress& listenAddr,
                     const string& nameArg,
                     Option option)
  : loop_(CHECK_NOTNULL(loop)),
    ipPort_(listenAddr.toIpPort()),
    name_(nameArg),
    acceptor_(new Acceptor(loop, listenAddr, option == kReusePort)),
    threadPool_(new EventLoopThreadPool(loop, name_)),
    connectionCallback_(defaultConnectionCallback),
    messageCallback_(defaultMessageCallback),
    nextConnId_(1)
{
  acceptor_->setNewConnectionCallback(
      std::bind(&TcpServer::newConnection, this, _1, _2));
}

最重要的是  acceptor_(new Acceptor(loop, listenAddr, option == kReusePort)),服务器首先需要一个监听套接字来监听是否有新的连接加入,而Acceptor负责监听套接字的创建和端口绑定。

void start(){
      threadPool_->start(threadInitCallback_);   //启动线程池管理器
    loop_->runInLoop(
        std::bind(&Acceptor::listen, get_pointer(acceptor_))); //把Acceptor::listen()加入调度队列或立即调用

};  

 

//处理监听套接字接收到的新的连接请求

//此函数被注册到Acceptor::newConnectionCallback(在TcpServer的构造函数中注册),之后被Acceptor::handleRead()中accept()新连接后调用

void TcpServer::newConnection(int sockfd, const InetAddress& peerAddr);

{

EventLoop* ioLoop=threadPool_->getNextLoop();     //线程池中取一个线程分配给新建连接 RR方式

TcpConnectionPtr conn(new TcpConnection(ioLoop,
                                          connName,
                                          sockfd,
                                          localAddr,
                                          peerAddr));     // 创建一个TcpConnextion对象,表示每一个已连接

  connections_[connName] = conn;

conn->setConnectionCallback(connectionCallback_);        //   connectionCallback_,messageCallback_,writeCompleteCallback_需要用户来提供,应该会注册到TcpConnection中的Channel对象的中

conn->setMessageCallback(messageCallback_);
  conn->setWriteCompleteCallback(writeCompleteCallback_);
  conn->setCloseCallback(
      std::bind(&TcpServer::removeConnection, this, _1)); // FIXME: unsafe
  ioLoop->runInLoop(std::bind(&TcpConnection::connectEstablished, conn));

}

 

我的理解是首先创建一个EventLoop(有点儿主线程的意思,),创建一个TcpServer来管理监听的套接字和连接套接字的信息,Acceptor class负责监听套接字,这是一个内部类,对外是隐藏的。当poll被监听套接字激活时,调用AcceptChannel中的handleEvent(),在handleEvent()中从线程池中取得一个线程(采用RR的方法),并且new一个TcpConnection对象,TcpConnection负责管理连接套接字,每一个连接套接字有一个TcpConnection相对应,这个线程负责处理该已连接套接字。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值