1、muduo网络库 ---- Linux平台下muduo编译安装

muduo库的介绍:一个基于reactor反应堆模型的多线程C++网络库。作者是陈硕大神。

muduo库是基于 boost 库开发的,所以需要在 Linux 平台上首先安装 boost 库。

1、boost 库安装

1、编译源码安装

第一种方法是编译源码安装,可以了解一下,不过比较麻烦:

  • 1、准备好boost压缩包,我这里是boost_1_65_0.tar.gz
  • 2、解压  tar -zxvf boost_1_65_0.tar.gz /usr/local
  • 3、进入/usr/local/boost_1_65_0目录,执行./bootstrap.sh
  • 4、执行./bjam
  • 5、执行./b2
  • 6、cp -rf boost /usr/include 
  • 7、cp -rf stage/lib/* /usr/lib

        因为g++会自动从/usr/include和/usr/local/lib路径下寻找所需要的文件。所以把这两部分复制到其中,当然也可以用软连接或者其他方式,使得程序在运行时候找到动态库。

2、操作系统仓库安装

在现在比较新的 Centos 或者 Ubuntu中,可以直接用操作系统仓库中的去安装,以Centos为例

  • yum install boost
  • yum install boost-devel
  • yum install boost-doc

这样就安装好了,然后可以进行测试,以下面代码为例,编译命令为

  • g++ b.cpp -g -o b -lboost_thread

#include <boost/thread/thread.hpp> 
#include <iostream>
#include <cstdlib>
using namespace std;

volatile bool isRuning = true;

void func1(){
    static int cnt1 = 0;
    while(isRuning){
        cout << "func1:" << cnt1++ << endl;
        sleep(1);
    }
}

void func2(){
    static int cnt2 = 0;
    while(isRuning){
        cout << "\tfunc2:" << cnt2++ << endl;
        sleep(2);
    }
}

int main()
{
    boost::thread thread1(&func1);
    boost::thread thread2(&func2);

    system("read");
    isRuning = false;

    thread2.join();
    thread1.join();
    cout << "exit" << endl;
    return 0;
}

2、安装muduo库

需要 下载源码自己进行编译,步骤比较简单。

1、下载源代码,解压

root@tony:/home/tony/package# ls
muduo-master.zip
root@tony:/home/tony/package# unzip muduo-master.zip

2、进入解压缩文件,修改CMakeList.txt(可选) 

root@tony:/home/tony/package# ls
muduo-master  muduo-master.zip
root@:/home/tony/package# cd muduo-master
root@t:/home/tony/package/muduo-master# ls
BUILD.bazel  ChangeLog2             contrib   muduo    WORKSPACE
build.sh     CMakeLists.txt         examples  patches
ChangeLog    compile_commands.json  License   README

此步骤可做可不做,就是修改CMakeLists.txt文件,
muduo库源码编译会编译很多unit_test测试用例代码,
编译耗时长,我们也用不到,
vim编辑上面源码目录里面的CMakeLists.txt文件,如下修改:
  7 if(NOT CMAKE_BUILD_TYPE)
  8   set(CMAKE_BUILD_TYPE "Release")
  9 endif()
 10 
 11 # only build examples if this is the main project
 12 if(CMAKE_PROJECT_NAME STREQUAL "muduo")
 13 #  option(MUDUO_BUILD_EXAMPLES "Build Muduo examples" ON)
 14 endif()
 15 
将13行 option(MUDUO_BUILD_EXAMPLES "Build Muduo examples" ON) 注释掉,保存并退出

3、编译,安装

有一个build.sh源码编译构建程序,运行该程序,muduo是用cmake来构建的,
需要先安装cmake,ubuntu下直接sudo apt install cmake就可以,
redhat或者centos可以从yum仓库直接安装。
进行编译。
root@tony:/home/tony/package/muduo-master# ./build.sh

编译完成后安装
root@tony:/home/tony/package/muduo-master# ./build.sh install
这个  ./build.sh install  实际上把muduo的头文件和lib库文件
放到了muduo-master同级目录下的build目录下
的release-install-cpp11文件夹下面了,可自行查看。

 4、设置头文件库文件位置

上面的install命令并没有把它们拷贝到系统路径下,
导致我们每次编译程序都需要指定muduo库的头文件和库文件路径,
所以把inlcude(头文件)和lib(库文件)目录下的文件拷贝到系统目录下或者建立软链接。

root@tony:build/release-install-cpp11/include# mv muduo/ /usr/include/
root@tony:build/release-install-cpp11/include# cd ..
root@tony:build/release-install-cpp11# ls
include  lib
root@:build/release-install-cpp11# cd lib/
root@tony:build/release-install-cpp11/lib# ls
libmuduo_base.a  libmuduo_http.a  libmuduo_inspect.a  libmuduo_net.a
root@tony:build/release-install-cpp11/lib# mv * /usr/local/lib/

完成以后使用muduo库编写C++网络程序,不用在指定头文件和lib库文件路径信息了,
因为g++会自动从/usr/include和/usr/local/lib路径下寻找所需要的文件。

在测试之前,补充一个知识点:

运行由链接库生成的可执行文件时,必须确保程序运行时可以找到所有需要的链接库。常用的解决方案有如下几种:

  • 将链接库文件移动到标准库目录下(例如 /usr/lib、/usr/lib64、/lib、/lib64),或者软链接
  • 在终端输入export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxx,其中xxx为动态链接库文件的绝对存储路径(此方式仅在当前终端有效,关闭终端后无效);
  • 修改~/.bashrc~/.bash_profile文件,即在文件最后一行添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxxxxx为动态库文件的绝对存储路径)。保存之后,执行source .bashrc指令(此方式仅对当前登陆用户有效)

测试:

#include <muduo/net/TcpServer.h>
#include <muduo/base/Logging.h>
#include <boost/bind.hpp>
#include <muduo/net/EventLoop.h>

// 使用muduo开发回显服务器
class EchoServer
{
 public:
  EchoServer(muduo::net::EventLoop* loop,
             const muduo::net::InetAddress& listenAddr);

  void start(); 

 private:
  void onConnection(const muduo::net::TcpConnectionPtr& conn);

  void onMessage(const muduo::net::TcpConnectionPtr& conn,
                 muduo::net::Buffer* buf,
                 muduo::Timestamp time);

  muduo::net::TcpServer server_;
};

EchoServer::EchoServer(muduo::net::EventLoop* loop,
                       const muduo::net::InetAddress& listenAddr)
  : server_(loop, listenAddr, "EchoServer")
{
  server_.setConnectionCallback(
      boost::bind(&EchoServer::onConnection, this, _1));
  server_.setMessageCallback(
      boost::bind(&EchoServer::onMessage, this, _1, _2, _3));
}

void EchoServer::start()
{
  server_.start();
}

void EchoServer::onConnection(const muduo::net::TcpConnectionPtr& conn)
{
  LOG_INFO << "EchoServer - " << conn->peerAddress().toIpPort() << " -> "
           << conn->localAddress().toIpPort() << " is "
           << (conn->connected() ? "UP" : "DOWN");
}

void EchoServer::onMessage(const muduo::net::TcpConnectionPtr& conn,
                           muduo::net::Buffer* buf,
                           muduo::Timestamp time)
{
  // 接收到所有的消息,然后回显
  muduo::string msg(buf->retrieveAllAsString());
  LOG_INFO << conn->name() << " echo " << msg.size() << " bytes, "
           << "data received at " << time.toString();
  conn->send(msg);
}


int main()
{
  LOG_INFO << "pid = " << getpid();
  muduo::net::EventLoop loop;
  muduo::net::InetAddress listenAddr(8888);
  EchoServer server(&loop, listenAddr);
  server.start();
  loop.loop();
}

使用g++进行编译,注意链接muduo和pthread的库文件,编译命令如下:

g++ main.cpp -lmuduo_net -lmuduo_base -lpthread -std=c++11

编译链接完成,生成a.out可执行程序,上面的echo服务器监听8888端口,运行上面的a.out回显服务器如下:

root@tony:/home/tony/code# ./a.out 
20190404 08:00:15.254790Z 42660 INFO  pid = 42660 - main.cpp:61

等待客户端连接,可以打开一个新的shell命令行用netcat命令模拟客户端连接echo服务器进行功能测试,命令如下:

tony@tony:~$ echo "hello world" | nc localhost 8888
hello world

客户端数据回显正确,看看服务器接日志信息打印如下:

root@tony:/home/tony/code# ./a.out 
20190404 08:00:15.254790Z 42660 INFO  pid = 42660 - main.cpp:61
20190404 08:00:59.438626Z 42660 INFO  TcpServer::newConnection [EchoServer] - new connection [EchoServer-0.0.0.0:8888#1] from 127.0.0.1:33480 - TcpServer.cc:80
20190404 08:00:59.438707Z 42660 INFO  EchoServer - 127.0.0.1:33480 -> 127.0.0.1:8888 is UP - main.cpp:42
20190404 08:00:59.438812Z 42660 INFO  EchoServer-0.0.0.0:8888#1 echo 12 bytes, data received at 1554364859.438723 - main.cpp:53

到此,muduo安装成功。
 

  • 11
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Linux多线程服务端编程:使用muduo C++网络》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。 目 录 第1部分C++ 多线程系统编程 第1章线程安全的对象生命期管理3 1.1当析构函数遇到多线程. . . . . . . . . . . . . . . . .. . . . . . . . . . . 3 1.1.1线程安全的定义. . . . . . . . . . . . . . . . .. . . . . . . . . . . 4 1.1.2MutexLock 与MutexLockGuard. . . . . . . . . . . . . . . . . . . . 4 1.1.3一个线程安全的Counter 示例.. . . . . . . . . . . . . . . . . . . 4 1.2对象的创建很简单. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 5 1.3销毁太难. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 7 1.3.1mutex 不是办法. . . . . . . . . . . . . . . . . . . .. . . . . . . . 7 1.3.2作为数据成员的mutex 不能保护析构.. . . . . . . . . . . . . . 8 1.4线程安全的Observer 有多难.. . . . . . . . . . . . . . . . . . . . . . . . 8 1.5原始指针有何不妥. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 11 1.6神器shared_ptr/weak_ptr . . . . . . . . . .. . . . . . . . . . . . . . . . 13 1.7插曲:系统地避免各种指针错误. . . . . . . . . . . . . . . . .. . . . . . 14 1.8应用到Observer 上.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.9再论shared_ptr 的线程安全.. . . . . . . . . . . . . . . . . . . . . . . . 17 1.10shared_ptr 技术与陷阱. . . .. . . . . . . . . . . . . . . . . . . . . . . . 19 1.11对象池. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . 21 1.11.1enable_shared_from_this . . . . . . . . . . . . . . . . . . . . . . 23 1.11.2弱回调. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 24 1.12替代方案. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 26 1.13心得与小结. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 26 1.14Observer 之谬. . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 第2章线程同步精要 2.1互斥器(mutex). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 2.1.1只使用非递归的mutex . . . . . . . . . . . . . .. . . . . . . . . . 33 2.1.2死锁. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 35 2.2条件变量(condition variable). . . . . . . . . .

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值