muduo库的使用

准备

使用muduo的好处就是能分离网络I/O代码与业务代码

依赖

1
libmuduo_base.so  libmuduo_net.so libpthread.so

muduo网络库提供了两个主要的类:TcpServer(编写服务端程序)、TcpClient(编写客户端程序)

基于muduo开发服务器程序

  1. 首先要组合TcpServer对象,即在类中声明私有对象
  2. 创建事件循环的指针
1
2
3
4
5
6
7
8
class EchoServer
{
public:

private:
muduo::net::TcpServer server_;
muduo::net::EventLoop *loop_;
};
  1. 根据 TcpServer需要的参数,写出主类的构造函数
1
2
3
4
TcpServer(EventLoop* loop, //事件循环(反应堆)
const InetAddress& listenAddr, //ip和端口号
const string& nameArg, //TcpServer的名字
Option option = kNoReusePort); //
1
2
3
4
5
EchoServer(muduo::net::EventLoop *loop, 
const muduo::net::InetAddress &listenAddr,
const muduo::string &nameArg) : server_(loop, listenAddr, nameArg), loop_(loop) {

}
  1. 给服务器注册用户断开和连接的回调函数、以及用户读写事件的回调函数(这里和QT很像,都是写在构造函数中,且回调函数都需要是void返回值)其中muduo::_1为参数占位符
1
2
3
4
5
6
7
8
EchoServer(muduo::net::EventLoop *loop,
const muduo::net::InetAddress &listenAddr,
const muduo::string &nameArg) : server_(loop, listenAddr, nameArg), loop_(loop) {
server_.setConnectionCallback(
bind(&EchoServer::onConnection, this, muduo::_1));
server_.setMessageCallback(
bind(&EchoServer::onMessage, this, muduo::_1, muduo::_2, muduo::_3));
}

这里还要实现一下onConnection和onMessage,这两个回调函数

1
2
3
4
5
6
7
8
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_;
muduo::net::EventLoop *loop_;
  1. 此时还要设置服务器的线程数量,muduo会自己划分I/O线程和worker线程。例如,一个I/O线程,三个worker线程
1
server_.setThreadNum(4);
  1. 开启事件循环
1
2
3
4
//开启事件循环
void start(){
server_.start();
};

服务端完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <muduo/net/TcpServer.h>
#include <muduo/base/Logging.h>
#include <muduo/net/EventLoop.h>
#include "string"
#include "functional"

// 使用muduo开发回显服务器
class EchoServer {
public:
EchoServer(muduo::net::EventLoop *loop,
const muduo::net::InetAddress &listenAddr,
const muduo::string &nameArg) : server_(loop, listenAddr, nameArg), loop_(loop) {
//给服务器注册用户断开和连接的回调函数
server_.setConnectionCallback(
bind(&EchoServer::onConnection, this, muduo::_1));
//用户读写事件的回调函数
server_.setMessageCallback(
bind(&EchoServer::onMessage, this, muduo::_1, muduo::_2, muduo::_3));

server_.setThreadNum(4);
}
//开启事件循环
void start(){
server_.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_;
muduo::net::EventLoop *loop_;
};

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("127.0.0.1",6000);
EchoServer server(&loop, listenAddr,"test");
server.start(); //把listenfd通过epoll_ctl添加到epoll上
loop.loop(); //相当于调用epoll_wait,按照阻塞方式等待新用户连接/已连接用户的读写事件
}

测试

编译

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

启动服务端:

1
2
./a.out
20230601 07:17:05.220492Z 16968 INFO pid = 16968 - UseMuduo.cpp:56

客户端发送信息:

1
echo "hello world" | nc localhost 6000

服务端:

1
2
3
20230601 07:07:26.551883Z 15967 INFO  TcpServer::newConnection [test] - new connection [test-127.0.0.1:6000#1] from 127.0.0.1:59254 - TcpServer.cc:80
20230601 07:07:26.552051Z 15968 INFO EchoServer - 127.0.0.1:59254 -> 127.0.0.1:6000 is UP - UseMuduo.cpp:39
20230601 07:07:26.552133Z 15968 INFO test-127.0.0.1:6000#1 echo 12 bytes, data received at 1685603246.552078 - UseMuduo.cpp:50

muduo库的使用
https://macbook-pro-gala.github.io/2023/06/08/muduo库的使用/
作者
lyh
发布于
2023年6月8日
许可协议