Muduo is a multithreaded C++ network library based on the reactor pattern.
muduo库的介绍就是:一个基于reactor反应堆模型的多线程C++网络库。
muduo网络库是C++语言开发的一个非常优秀的网络库,作者陈硕,muduo网络库在多线程环境下性能非常高,该系列文章会分享一些muduo库源码的知识,包括它的线程池源码,TcpServer源码,还有很多muduo库应用的示例代码等,学习一下作者优秀的C++多线程网络编程设计思想。
这篇文章主要讲Linux平台下muduo网络库的源码编译安装,用来开发网络高并发程序。
【注意】:muduo库是基于boost开发的,所以需要先在Linux平台上安装boost库
boost源码包下载链接:https://www.boost.org/
1.下载完成后,先把Linux系统下的boost源码包boost_1_69_0.tar.gz拷贝到某一指定路径下,然后解压:
bash
tar -zxvf boost_1_69_0.tar.gz
2.进入解压好的文件夹中,用ls命令查看:
bash
ls
boost boostcpp.jam boost.png bootstrap.sh index.htm INSTALL libs more status
boost-build.jam boost.css bootstrap.bat doc index.html Jamroot LICENSE_1_0.txt rst.css tools
3.运行bootstrap.sh工程编译构建程序,需要等待一会儿,查看目录:
bash
./boostrap.sh
4.源码根目录下生成了b2程序,运行b2程序如下(boost源码比较大,这里编译需要花费一些时间):
【注意】:如果Linux系统没有安装g++编译器,需要先安装g++,建议g++4.6版本以上,能比较好的支持C++新标准,可以通过命令 g++ --version 查看g++版本号。
bash
./b2
编译完成后,会有如下打印:
The Boost C++ Libraries were successfully built!
最后,再把上面的boost库头文件和lib库文件安装在默认的Linux系统头文件和库文件的搜索路径下,运行下面命令(因为要给/usr目录下拷贝文件,需要先进入root用户):
bash
sudo ./b2 install
安装完成后,最后会有如下信息打印出来:
测试一下是否安装成功:
cpp
#include <iostream>
#include <boost/bind.hpp>
#include <string>
using namespace std;
class Hello
{
public:
void say(string name)
{
cout << name << " say: hello world!" << endl;
}
};
int main()
{
Hello h;
auto func = boost::bind(&Hello::say, &h, "jyx");
func();
return 0;
}
安装好了boost库的源码之后,我们现在开始安装muduo网络库:
1.拷贝muduo的源码压缩包muduo-master.zip到Linux系统下,
bash
jyx@ubuntu:~/boost$ ls
boost_1_86_0 boost_1_86_0.tar.gz muduo-master.zip
jyx@ubuntu:~/boost$ unzip muduo-master.zip
2.解压完成后,进入muduo库的解压目录里面
注意,muduo库源码编译会编译很多unit_test测试用例代码,编译耗时长,我们也用不到,vim编辑上面源码目录里面的CMakeLists.txt文件,如下修改:
保存并退出,继续下面的步骤。
3.看到有一个build.sh源码编译构建程序,运行该程序(注意:muduo是用cmake来构建的,需要先安装cmake,ubuntu下直接sudo apt-get install cmake就可以,redhat或者centos可以从yum仓库直接安装):
拿ubuntu举例,如果没有安装cmake,执行下面的命令安装cmake:
bash
sudo apt-get install cmake
然后执行build.sh程序:
bash
./build.sh
4.编译完成后,在输入./build.sh install命令进行muduo库安装
安装完成后,返回上一级目录,我们看到多了一个build目录,进去看看:
再进入后面的那个文件夹:
这就是muduo库的头文件和库文件了。
上面的install命令并没有把它们拷贝到系统路径下,导致我们每次编译程序都需要指定muduo库的头文件和库文件路径,很麻烦,所以我们选择直接把inlcude(头文件)和lib(库文件)目录下的文件拷贝到系统目录下:
这样就算安装好了,我们写一段测试代码:
cpp
#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的库文件,编译命令如下:
bash
g++ main.cpp -lmuduo_net -lmuduo_base -lpthread -std=c++11
这是运行结果。
等待客户端连接,可以打开一个新的shell命令行用netcat命令模拟客户端连接echo服务器进行功能测试,命令如下:
bash
echo "hello world" | nc localhost 8888
返回服务器端查看日志:
这样muduo库就安装成功了。