渝村 發表於 2025-7-14 00:00:00

在Ubuntu上安装 Muduo网络库的详细指南

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>1. 更新系统包列表</li><li>2. 安装必要的依赖项</li><li>3. 克隆&nbsp;Muduo&nbsp;的源码仓库</li><li>4. 创建构建目录并编译</li><li>5. 安装 Muduo(可选)</li><li>6. 配置环境变量(如果需要)</li><li>7. 验证安装</li><li>8. 编写自己的项目</li><li>9.测试代码</li><li>常见问题及解决方案</li><li>Muduo 库常见接口<ul class="second_class_ul"><li>TcpServer类</li><li>EventLoop类</li><li>TcpConnection类</li><li>TcpClient类</li><li>Buffer类</li></ul></li></ul></div><p>环境:ubuntu 24.04</p>
<p class="maodian"></p><h2>1. 更新系统包列表</h2>
<p>首先,确保你的系统包列表是最新的。</p>
<div class="dxycode"><pre class="brush:bash;">sudo apt-get update
sudo apt-get upgrade</pre></div>
<p class="maodian"></p><h2>2. 安装必要的依赖项</h2>
<p>Muduo依赖于一些基本的开发工具和库。安装这些依赖项:</p>
<div class="dxycode"><pre class="brush:bash;">sudo apt-get install -y git cmake g++ libboost-all-dev libssl-dev</pre></div>
<ul><li><strong>git</strong>:用于克隆 Muduo 的源码仓库。</li><li><strong>cmake</strong>:用于构建项目。</li><li><strong>g++</strong>:C++ 编译器。</li><li><strong>libboost-all-dev</strong>:Boost 库,Muduo 依赖于 Boost。</li><li><strong>libssl-dev</strong>:用于 SSL 支持(如果需要)。</li></ul>
<p class="maodian"></p><h2>3. 克隆&nbsp;Muduo&nbsp;的源码仓库</h2>
<p>使用 git 克隆 Muduo 的源码。Muduo 的官方仓库托管在 GitHub 上。</p>
<div class="dxycode"><pre class="brush:bash;">git clone https://github.com/chenshuo/muduo.git</pre></div>
<p class="maodian"></p><h2>4. 创建构建目录并编译</h2>
<p>进入 Muduo 源码目录,创建一个构建目录,并使用 CMake 进行编译。</p>
<div class="dxycode"><pre class="brush:bash;">cd muduo
mkdir build
cd build
cmake ..
make</pre></div>
<p style="text-align:center"><img style="max-width:100%!important;height:auto!important;"alt="" src="https://zhuji.jb51.net/uploads/allimg/20250714/2-250G4115F4316.png" /></p>
<p class="maodian"></p><h2>5. 安装 Muduo(可选)</h2>
<p>如果你希望将 Muduo 安装到系统目录,可以执行以下命令:</p>
<div class="dxycode"><pre class="brush:bash;">sudo make install</pre></div>
<p style="text-align:center"><img style="max-width:100%!important;height:auto!important;"alt="" src="https://zhuji.jb51.net/uploads/allimg/20250714/2-250G4115F45B.png" /></p>
<p>默认情况下,Muduo 会被安装到 <code>/usr/local</code> 目录下。如果需要自定义安装路径,可以在运行 <code>cmake</code> 时指定 <code>CMAKE_INSTALL_PREFIX</code>:</p>
<div class="dxycode"><pre class="brush:bash;">cmake -DCMAKE_INSTALL_PREFIX=/your/custom/path ..
make
sudo make install</pre></div>
<p class="maodian"></p><h2>6. 配置环境变量(如果需要)</h2>
<p>如果你将 Muduo 安装到了自定义路径,可能需要将库路径添加到 <code>LD_LIBRARY_PATH</code> 环境变量中。</p>
<div class="dxycode"><pre class="brush:bash;">export LD_LIBRARY_PATH=/your/custom/path/lib:$LD_LIBRARY_PATH</pre></div>
<p>你可以将上述命令添加到 <code>~/.bashrc</code> 或 <code>~/.profile</code> 文件中,以便每次启动终端时自动设置。</p>
<p class="maodian"></p><h2>7. 验证安装</h2>
<p>你可以编译并运行 Muduo 提供的示例程序,确保安装成功。</p>
<div class="dxycode"><pre class="brush:bash;">cd ../examples
make
./echo_server</pre></div>
<p>如果 <code>echo_server</code> 启动成功并监听指定端口,说明 Muduo 安装成功。</p>
<p class="maodian"></p><h2>8. 编写自己的项目</h2>
<p>在你的项目中使用 Muduo 时,需要在 <code>CMakeLists.txt</code> 中添加相应的配置。例如:</p>
<div class="dxycode"><pre class="brush:plain;">cmake_minimum_required(VERSION 3.10)
project(MyMuduoApp)
set(CMAKE_CXX_STANDARD 11)
find_package(muduo REQUIRED)
add_executable(MyMuduoApp main.cpp)
target_link_libraries(MyMuduoApp muduo_net muduo_base pthread)</pre></div>
<p>确保 <code>main.cpp</code> 中包含 Muduo 的头文件并使用其功能。</p>
<p class="maodian"></p><h2>9.测试代码</h2>
<p>把muduo库的头文件和lib库文件拷贝完成以后,使用muduo库编写一个简单的echo回显服务器,测试muduo库是否可以正常使用,代码如下:</p>
<div class="dxycode"><pre class="brush:cpp;">#include &lt;muduo/net/TcpServer.h&gt;
#include &lt;muduo/base/Logging.h&gt;
#include &lt;boost/bind.hpp&gt;
#include &lt;muduo/net/EventLoop.h&gt;
// 使用muduo开发回显服务器
class EchoServer
{
public:
EchoServer(muduo::net::EventLoop* loop,
             const muduo::net::InetAddress&amp; listenAddr);
void start();
private:
void onConnection(const muduo::net::TcpConnectionPtr&amp; conn);
void onMessage(const muduo::net::TcpConnectionPtr&amp; conn,
               muduo::net::Buffer* buf,
               muduo::Timestamp time);
muduo::net::TcpServer server_;
};
EchoServer::EchoServer(muduo::net::EventLoop* loop,
                     const muduo::net::InetAddress&amp; listenAddr)
: server_(loop, listenAddr, "EchoServer")
{
server_.setConnectionCallback(
      boost::bind(&amp;EchoServer::onConnection, this, _1));
server_.setMessageCallback(
      boost::bind(&amp;EchoServer::onMessage, this, _1, _2, _3));
}
void EchoServer::start()
{
server_.start();
}
void EchoServer::onConnection(const muduo::net::TcpConnectionPtr&amp; conn)
{
LOG_INFO &lt;&lt; "EchoServer - " &lt;&lt; conn-&gt;peerAddress().toIpPort() &lt;&lt; " -&gt; "
         &lt;&lt; conn-&gt;localAddress().toIpPort() &lt;&lt; " is "
         &lt;&lt; (conn-&gt;connected() ? "UP" : "DOWN");
}
void EchoServer::onMessage(const muduo::net::TcpConnectionPtr&amp; conn,
                           muduo::net::Buffer* buf,
                           muduo::Timestamp time)
{
// 接收到所有的消息,然后回显
muduo::string msg(buf-&gt;retrieveAllAsString());
LOG_INFO &lt;&lt; conn-&gt;name() &lt;&lt; " echo " &lt;&lt; msg.size() &lt;&lt; " bytes, "
         &lt;&lt; "data received at " &lt;&lt; time.toString();
conn-&gt;send(msg);
}
int main()
{
LOG_INFO &lt;&lt; "pid = " &lt;&lt; getpid();
muduo::net::EventLoop loop;
muduo::net::InetAddress listenAddr(8888);
EchoServer server(&amp;loop, listenAddr);
server.start();
loop.loop();
}</pre></div>
<p>使用g++进行编译,注意链接muduo和pthread的库文件,编译命令如下:</p>
<div class="dxycode"><pre class="brush:bash;">g++ main.cpp -lmuduo_net -lmuduo_base -lpthread -std=c++11</pre></div>
<p>编译链接完成,生成a.out可执行程序,上面的echo服务器监听8888端口,运行上面的a.out回显服务器如下:</p>
<div class="dxycode"><pre class="brush:bash;">darling@darling:~/桌面$ ./a.out
20241221 06:50:24.057765Z 10774 INFOpid = 10774 - test.cpp:61</pre></div>
<p style="text-align:center"><img style="max-width:100%!important;height:auto!important;"alt="" src="https://zhuji.jb51.net/uploads/allimg/20250714/2-250G4115G03O.png" /></p>
<p>等待客户端连接,可以打开一个新的shell命令行用netcat命令模拟客户端连接echo服务器进行功能测试,命令如下:</p>
<div class="dxycode"><pre class="brush:bash;">darling@darling:~$ nc 127.0.0.1 8888
hello world
hello world
nihao a
nihao a</pre></div>
<p style="text-align:center"><img style="max-width:100%!important;height:auto!important;"alt="" src="https://zhuji.jb51.net/uploads/allimg/20250714/2-250G4115G0A2.png" /></p>
<p class="maodian"></p><h2>常见问题及解决方案</h2>
<ul><li><strong>Boost 版本问题</strong>:确保安装的 Boost 版本与 Muduo 兼容。一般来说,Ubuntu 仓库中的 Boost 版本是足够的。</li><li><strong>权限问题</strong>:如果在安装过程中遇到权限问题,确保使用&nbsp;<code>sudo</code>&nbsp;执行需要权限的命令。</li><li><strong>依赖缺失</strong>:如果编译过程中提示缺少依赖项,安装相应的开发包。例如,如果缺少&nbsp;<code>openssl</code>,可以安装&nbsp;<code>libssl-dev</code>。</li></ul>
<p class="maodian"></p><h2>Muduo 库常见接口</h2>
<p class="maodian"></p><h3>TcpServer类</h3>
<p>TcpServer 类负责管理网络服务端的行为,包括启动服务器、设置网络连接的回调函数以及消息处理的回调函数。这样可以灵活地定义在不同网络事件发生时执行的具体操作,例如接受新连接、连接断开或数据接收等。</p>
<p>下面来认识一下 TcpServer 的主要接口:</p>
<div class="dxycode"><pre class="brush:cpp;">typedef std::shared_ptr&lt;TcpConnection&gt; TcpConnectionPtr;
typedef std::function&lt;void (const TcpConnectionPtr&amp;)&gt; ConnectionCallback;
typedef std::function&lt;void (const TcpConnectionPtr&amp;,
Buffer*,
Timestamp)&gt; MessageCallback;
class InetAddress : public muduo::copyable
{
public:
InetAddress(StringArg ip, uint16_t port, bool ipv6 = false);
};
class TcpServer : noncopyable
{
        public:
        enum Option
        {
                kNoReusePort,
                kReusePort,
        };
       TcpServer(EventLoop* loop,
        const InetAddress&amp; listenAddr,
        const string&amp; nameArg,
       Option option = kNoReusePort);
        void setThreadNum(int numThreads);
        void start();
        /// 当⼀个新连接建⽴成功的时候被调⽤
        void setConnectionCallback(const ConnectionCallback&amp; cb)
        { connectionCallback_ = cb; }
        /// 消息的业务处理回调函数---这是收到新连接消息的时候被调⽤的函数
        void setMessageCallback(const MessageCallback&amp; cb)
        { messageCallback_ = cb; }
};</pre></div>
<p class="maodian"></p><h3>EventLoop类</h3>
<p>EventLoop 类是事件循环的核心,负责启动和管理事件监控循环。通过这个循环,服务器可以非阻塞地监听和响应网络事件(如新的连接请求、数据到达等)。它还支持通过定时任务来调度将来某一时刻执行的任务,这对于需要定时检查或更新状态的应用非常有用。</p>
<div class="dxycode"><pre class="brush:cpp;">class EventLoop
{
    void loop();// 开始事件监控循环
    void quit();// 停止循环
    Timerld runAfter(delay, cb);// 定时任务
};</pre></div>
<p class="maodian"></p><h3>TcpConnection类</h3>
<p>TcpConnection 类管理着每个网络连接的状态,提供发送数据、检查连接状态和关闭连接的功能。它的设计使得每个连接可以独立地处理其生命周期内的各种事件。</p>
<div class="dxycode"><pre class="brush:cpp;">class TcpConnection
{
    TcpClient(EventLoop* loop, const InetAddress&amp; serverAddr, const string&amp; nameArg);
    void send(std::string &amp;msg);// 发送数据
    bool connected();// 当前连接是否连接正常
    void shutdown();// 关闭连接
};</pre></div>
<p class="maodian"></p><h3>TcpClient类</h3>
<p>TcpClient 是 Muduo 库中用于处理 TCP 客户端连接的类,它通过 EventLoop 来监控和处理IO事件。用户可以使用 connect() 和 disconnect() 控制连接,并通过 setConnectionCallback() 和 setMessageCallback() 设置回调函数,处理连接状态的变更和消息的接收。</p>
<div class="dxycode"><pre class="brush:cpp;">class TcpClient : noncopyable
{
public:
       // TcpClient(EventLoop* loop);
       // TcpClient(EventLoop* loop, const string&amp; host, uint16_t port);
       TcpClient(EventLoop* loop,
       const InetAddress&amp; serverAddr,
       const string&amp; nameArg);
       ~TcpClient(); // force out-line dtor, for std::unique_ptr members.
       void connect();//连接服务器
       void disconnect();//关闭连接
       void stop();
       //获取客⼾端对应的通信连接Connection对象的接⼝,发起connect后,有可能还没有连接建⽴成功
        TcpConnectionPtr connection() const
        {
               MutexLockGuard lock(mutex_);
               return connection_;
        }
        /// 连接服务器成功时的回调函数
       void setConnectionCallback(ConnectionCallback cb)
       { connectionCallback_ = std::move(cb); }
       /// 收到服务器发送的消息时的回调函数
        void setMessageCallback(MessageCallback cb)
        { messageCallback_ = std::move(cb); }
private:
       EventLoop* loop_;
       ConnectionCallback connectionCallback_;
       MessageCallback messageCallback_;
        WriteCompleteCallback writeCompleteCallback_;
        TcpConnectionPtr connection_ GUARDED_BY(mutex_);
};
/*
需要注意的是,因为muduo库不管是服务端还是客⼾端都是异步操作,
对于客⼾端来说如果我们在连接还没有完全建⽴成功的时候发送数据,这是不被允许的。
因此我们可以使⽤内置的CountDownLatch类进⾏同步控制
*/
class CountDownLatch : noncopyable
{
public:
       explicit CountDownLatch(int count);
       void wait(){
               MutexLockGuard lock(mutex_);
                while (count_ &gt; 0)
                {
                       condition_.wait();
                }
        }
        void countDown(){
               MutexLockGuard lock(mutex_);
                --count_;
                if (count_ == 0)
                {
                       condition_.notifyAll();
                }
        }
        int getCount() const;
private:
        mutable MutexLock mutex_;
        Condition condition_ GUARDED_BY(mutex_);
        int count_ GUARDED_BY(mutex_);
}</pre></div>
<p class="maodian"></p><h3>Buffer类</h3>
<p>Buffer 类用于高效地管理数据缓冲区。它提供一系列操作来读取和处理存储在缓冲区中的数据,支持网络字节序的转换和数据的基本处理,如读取、检索和删除操作。这是处理TCP流数据的关键部分,因为网络数据可以随机到达,并且可能需要积累足够的数据才能进行处理。</p>
<div class="dxycode"><pre class="brush:cpp;">class Buffer
{
    size_t readableBytes() const;// 获取缓冲区大小
    const char* peek() const;// 获取缓冲区中数据的起始地址
    int32_t peekInt32() const;// 尝试从缓冲区获取4字节数据,进行网络字节序转换为整型,但不从缓冲区删除
    void retrieveInt32();// 数据读取位置向后偏移4字节(本质就是删除起始位置的4字节数据)
    int32_t readInt32();
    string retrieveAllAsString();// 从缓冲区取出所有数据并删除,以string形式返回
    string retrieveAsString(size_t len);// 从缓冲区读取len长度的数据并删除,以string形式返回
};</pre></div>
<p>以上就是在 Ubuntu 上安装 Muduo 网络库的详细指南的详细内容,更多相关资料请阅读琼殿技术社区其它文章!</p>
頁: [1]
查看完整版本: 在Ubuntu上安装 Muduo网络库的详细指南