[muduo网络库]——使用muduo库搭建Echo服务器(剖析muduo网络库核心部分、设计思想)

在此之前,我们对于muduo库的每一类几乎都进行了逐行的分析,但是一个网络库的每个模块之间总是有千丝万缕的关系,所以可能有的地方还是有分析的不到位,所以从这一篇开始,我们从muduo的简单使用----搭建一个Echo服务器,来一步一步的分析一下整个muduo库的内在联系。

TCP网络编程最本质是的处理三个半事件

连接建立:服务器accept(被动)接受连接,客户端connect(主动)发起连接
连接断开:主动断开(close、shutdown),被动断开(read返回0)
消息到达:客户端文件描述符可读
消息发送完毕:这算半个。对于低流量的服务,可不必关心这个事件;这里的发送完毕是指数据写入操作系统缓冲区,将由TCP协议栈负责数据的发送与重传,不代表对方已经接收到数据。
接下来,我们从这几个事件来梳理整个muduo库。

搭建Echo服务器

在学习一个网络库之前,我们一定是要先学会怎么使用这个网络库,接下来,我们搭建一个最简单的Echo服务器。

什么是Echo服务器

echo服务器,也称为回显服务器,简单来说就是服务端收到什么,就给客户端发送什么。

源码

#include <my_muduo/TcpServer.h>
#include <my_muduo/logger.h>

#include <string>
#include <functional>

class EchoServer
{
public:
    EchoServer(EventLoop *loop,
            const InetAddress &addr,
            const std::string &name)
        :server_(loop,addr,name)
        ,loop_(loop)
        {
            //注册回调函数
            server_.setConnectionCallback(
                std::bind(&EchoServer::onConnection,this,std::placeholders::_1)
            );

            server_.setMessageCallback(
                std::bind(&EchoServer::onMessage,this,
                    std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)
            );

            //设置合适的loop线程数量 loopThread
            server_.setThreadNum(3);
        }

    void start()
    {
        server_.start();
    }
private:
    //连接建立或者断开的回调
    void onConnection(const TcpConnectionPtr &conn)
    {
        if(conn->connected())
        {
            LOG_INFO("Connection UP : %s",conn->peerAddress().toIpPort().c_str());
        }
        else
        {
            LOG_INFO("Connection DOWN : %s",conn->peerAddress().toIpPort().c_str());
        }
    }

    //可读写事件回调
    void onMessage(const TcpConnectionPtr &conn,
                Buffer *buf,
                TimeStamp time)
        {
            std::string msg = buf->retrieveAllAsString();
            conn->send(msg);
            conn->shutdown(); //关闭写端EPOLLHUP=> closeCallback
        }
        
    EventLoop *loop_;
    TcpServer server_;
};

int main()
{
    EventLoop loop;
    InetAddress addr(8000);
    //Acceptor non-blocking listenfd create bind
    EchoServer server(&loop,addr,"EchoServer-01");
    //listen loopthread listenfd => acceptChannel => mainLoop => subloop
    server.start();
    loop.loop(); //启动mainloop的底层pooler

    return 0;
}

从代码中,我们可以看出来它一共做了如下几件事:

  • 创建了一个EventLoop: EventLoop loop;,这个EventLoop就是mainLoop,loop就是baseloop_
  • 指定了接收端口号,ip使用默认的127.0.0.1;
  • 创建了一个server对象,即TcpServer类对象 : TcpServer server_;,并传入了loop,addr,以及指定了对象名;
  • 启动TcpServer服务器,server.start();,调用TcpServer::start()
  • 开启事件循环: loop.loop();,调用EventLoop::loop()

代码地址:https://github.com/Cheeron955/mymuduo/tree/master

好了~ 使用muduo库搭建Echo服务器就到这里结束了,下一篇我们开始按照启动服务器,连接建立、消息收发、连接关闭的顺序来逐一剖析muduo网络库工作流程。下一节见~

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-16 08:46:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-16 08:46:03       101 阅读
  3. 在Django里面运行非项目文件

    2024-05-16 08:46:03       82 阅读
  4. Python语言-面向对象

    2024-05-16 08:46:03       91 阅读

热门阅读

  1. 基于图扩散嵌入网络的数据表示与学习 笔记

    2024-05-16 08:46:03       37 阅读
  2. 【无标题】

    2024-05-16 08:46:03       32 阅读
  3. leetcode hot100_part28_图论

    2024-05-16 08:46:03       36 阅读
  4. 基于C++和OpenCv对视频进行抽帧

    2024-05-16 08:46:03       33 阅读
  5. Leetcode 513:找树左下角的值

    2024-05-16 08:46:03       31 阅读
  6. 广播

    2024-05-16 08:46:03       33 阅读