muduo的TCPserver端初始化步骤,以EchoServer_unittest.cc为例

环境变量里加export MUDUO_LOG_TRACE=1使其打印出最多的日志

看这个库需要boost基础,这个专栏地址参考价值比较大

 EchoServer_unittest.cc代码如下

EventLoop loop;
  InetAddress listenAddr(2000, false, ipv6);
  EchoServer server(&loop, listenAddr);

  server.start();

  loop.loop();

1、EventLoop构造如下

EventLoop::EventLoop()
  : looping_(false),
    quit_(false),
    eventHandling_(false),
    callingPendingFunctors_(false),
    iteration_(0),
    threadId_(CurrentThread::tid()),
    poller_(Poller::newDefaultPoller(this)),
    timerQueue_(new TimerQueue(this)),
    wakeupFd_(createEventfd()),
    wakeupChannel_(new Channel(this, wakeupFd_)),
    currentActiveChannel_(NULL)
{
  LOG_DEBUG << "EventLoop created " << this << " in thread " << threadId_;
  LOG_TRACE << "wakeupFd_ = " << wakeupFd_ << " in thread " << threadId_;


以上这里poller_(Poller::newDefaultPoller(this)),new了个epoll对象代码如下

EPollPoller::EPollPoller(EventLoop* loop)
  : Poller(loop),
    epollfd_(::epoll_create1(EPOLL_CLOEXEC)),
    events_(kInitEventListSize)

使用新API接口:epoll_create1创建了个epollfd_


接着在epollfd_下挂了关注三个fd

timerQueue_(new TimerQueue(this)),这里创建了个timerfd,并弄成了Channel

wakeupFd_(createEventfd()),
    wakeupChannel_(new Channel(this, wakeupFd_)),

wakeupFd_  notify里用的 唤醒 EventLoop 的 是baseloop?待后面研究


EchoServer server(&loop, listenAddr);这句构造函数如下


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 和 EventLoopThreadPool

Acceptor::Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport)
  : loop_(loop),
    acceptSocket_(sockets::createNonblockingOrDie(listenAddr.family())),
    acceptChannel_(loop, acceptSocket_.fd()),
    listenning_(false),
    idleFd_(::open("/dev/null", O_RDONLY | O_CLOEXEC))
{
  assert(idleFd_ >= 0);
  LOG_TRACE << "acceptSocket_.fd = " << acceptSocket_.fd();

Acceptor这里就创建了acceptSocket_.fd

loop_是base pool  threadPool_是根据setThreadNum设置才有的


接着 server.start();代码如下启动监听

void TcpServer::start()
{
  if (started_.getAndSet(1) == 0)
  {
    threadPool_->start(threadInitCallback_);

    assert(!acceptor_->listenning());
    loop_->runInLoop(
        boost::bind(&Acceptor::listen, get_pointer(acceptor_)));
  }
}

Acceptor::listen里有acceptChannel_.enableReading();这句 ,类似Channel的enable系列里面都有 update 就最终在EPollPoller.cc文件里

TRACE updateChannel fd = 6 events = 3 index = -1 - EPollPoller.cc:113
20170830 12:39:39.678981Z  5875 TRACE update epoll_ctl op = ADD fd = 6 event = { 6: IN PRI  } - EPollPoller.cc:181

实现效果了

接着 void EventLoop::loop()就 pollReturnTime_ = poller_->poll(kPollTimeMs, &activeChannels_); poll在这个地方了

日志如下


[root@localhost bin]# ./echoserver_unittest
20170830 12:39:39.675537Z  5875 INFO  pid = 5875, tid = 5875 - EchoServer_unittest.cc:73
20170830 12:39:39.675809Z  5875 INFO  sizeof TcpConnection = 236 - EchoServer_unittest.cc:74
20170830 12:39:39.675863Z  5875 TRACE EPollPoller epollfd_ = 3 - EPollPoller.cc:45
20170830 12:39:39.675891Z  5875 TRACE Channel fd_ = 4 - Channel.cc:35
20170830 12:39:39.675904Z  5875 TRACE Channel loop_ = 0xBFD1F1E0 - Channel.cc:36
20170830 12:39:39.675910Z  5875 TRACE TimerQueue timerfd_ = 4 - TimerQueue.cc:102
20170830 12:39:39.675918Z  5875 TRACE updateChannel fd = 4 events = 3 index = -1 - EPollPoller.cc:113
20170830 12:39:39.676131Z  5875 TRACE update epoll_ctl op = ADD fd = 4 event = { 4: IN PRI  } - EPollPoller.cc:181
20170830 12:39:39.676167Z  5875 TRACE Channel fd_ = 5 - Channel.cc:35
20170830 12:39:39.676174Z  5875 TRACE Channel loop_ = 0xBFD1F1E0 - Channel.cc:36
20170830 12:39:39.676181Z  5875 DEBUG EventLoop EventLoop created 0xBFD1F1E0 in thread 5875 - EventLoop.cc:76
20170830 12:39:39.676192Z  5875 TRACE EventLoop wakeupFd_ = 5 in thread 5875 - EventLoop.cc:77
20170830 12:39:39.676205Z  5875 TRACE updateChannel fd = 5 events = 3 index = -1 - EPollPoller.cc:113
20170830 12:39:39.676219Z  5875 TRACE update epoll_ctl op = ADD fd = 5 event = { 5: IN PRI  } - EPollPoller.cc:181
20170830 12:39:39.676279Z  5875 TRACE Channel fd_ = 6 - Channel.cc:35
20170830 12:39:39.676287Z  5875 TRACE Channel loop_ = 0xBFD1F1E0 - Channel.cc:36
20170830 12:39:39.678890Z  5875 TRACE Acceptor acceptSocket_.fd = 6 - Acceptor.cc:34
20170830 12:39:39.678955Z  5875 TRACE updateChannel fd = 6 events = 3 index = -1 - EPollPoller.cc:113
20170830 12:39:39.678981Z  5875 TRACE update epoll_ctl op = ADD fd = 6 event = { 6: IN PRI  } - EPollPoller.cc:181
20170830 12:39:39.678993Z  5875 TRACE loop EventLoop 0xBFD1F1E0 start looping - EventLoop.cc:109
20170830 12:39:39.678999Z  5875 TRACE poll fd total count 3 - EPollPoller.cc:59
20170830 12:39:49.679514Z  5875 TRACE poll nothing happended - EPollPoller.cc:77
20170830 12:39:49.679567Z  5875 TRACE poll fd total count 3 - EPollPoller.cc:59
20170830 12:39:59.694012Z  5875 TRACE poll nothing happended - EPollPoller.cc:77
20170830 12:39:59.694126Z  5875 TRACE poll fd total count 3 - EPollPoller.cc:59
20170830 12:40:09.709135Z  5875 TRACE poll nothing happended - EPollPoller.cc:77
20170830 12:40:09.709186Z  5875 TRACE poll fd total count 3 - EPollPoller.cc:59
20170830 12:40:19.713299Z  5875 TRACE poll nothing happended - EPollPoller.cc:77
20170830 12:40:19.713349Z  5875 TRACE poll fd total count 3 - EPollPoller.cc:59




### 关于 `muduo` 中 `tcpserver.h` 文件缺失的原因分析 在使用 `muduo` 网络的过程中,如果遇到 `tcpserver.h` 文件缺失的情况,可能是由于以下几个原因造成的: #### 1. **未正确下载完整的源码包** 如果从不完整的资源或者错误的版本获取了 `muduo` 的源码,则可能导致某些头文件(如 `tcpserver.h`)不存在。建议重新确认是否已下载官方发布的完整版源码[^1]。 #### 2. **路径配置问题** 即使已经拥有完整的源码,在构建项目时如果没有正确设置包含路径 (`include path`) 或者链接器选项,也可能导致编译器无法找到该头文件。可以通过调整 CMakeLists.txt 中的相关配置来解决问题[^3]。 #### 3. **版本差异引起的兼容性问题** 不同版本之间可能存在 API 变更或结构调整,比如某个特定功能被移到其他模块里去了。因此需要仔细核对所使用的具体分支/标签号以及对应的文档说明[^2]。 --- ### 解决方案 以下是针对上述可能原因提出的几种解决办法: #### 方法一:验证并更新至最新稳定版本 确保当前操作基于最新的发布版本而非开发中的不稳定状态;访问 GitHub 官方仓页面查看 Release Notes 并按照指示升级代码基线。 ```bash git clone https://github.com/chenshuo/muduo.git cd muduo git checkout tags/vX.Y.Z # 替换 X.Y.Z 表示期望的目标发行编号 ``` #### 方法二:检查依赖关系与环境变量设定 对于跨平台工具链而言,有时缺少必要的外部支持也会间接影响内部组件可用性。如 Boost 是一个常见的前提条件之一,需事先完成其本地部署后再继续尝试安装 Muduo。 - 下载 Boost 源码压缩包解压后执行如下命令序列: ```bash ./bootstrap.sh --prefix=/usr/local/ sudo ./b2 install export BOOST_ROOT=/usr/local/include/boost ``` 随后修改 Makefile.am 添加额外标志 `-I${BOOST_ROOT}` 来告知预处理器查找位置。 #### 方法三:手动复制遗漏项回原目录结构内 假如经过排查发现确实存在个别重要单元遗失现象的话,可以从网上搜索相似主题帖子里面附带补丁附件直接应用上去即可恢复正常使用状况[^4]。 --- ### 示代码片段展示如何定义回调处理程序 下面给出一段简单的子演示怎样利用 TcpServer 类型创建服务器对象的同时注册消息到达事件监听逻辑部分: ```cpp #include "muduo/net/TcpServer.h" #include "muduo/net/EventLoop.h" using namespace muduo; using namespace muduo::net; void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp time){ std::string msg(buf->retrieveAllAsString()); LOG_INFO << conn->name() << " receives " << msg.size() << " bytes at " << time.toString(); } int main(){ EventLoop loop; InetAddress listenAddr(9981); TcpServer server(&loop,"TestServer",listenAddr); server.setThreadNum(3); // 设置多线程模式下的工作线程数量 server.setMessageCallback(onMessage); server.start(); loop.loop(); return 0; } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值