盛世宏图 发表于 前天 07:58

muduo网络库2

 
           Muduo网络库:底层实质上为Linux的epoll + pthread线程池,且依靠boost库。 muduo的网络计划焦点为一个线程一个变乱循环,有一个main Reactor负载accept连接,然后把连接分发到某个sub Reactor(采用轮询的方式来选择sub Reactor),该连接的所用操作都在谁人sub Reactor所处的线程中完成。多个连接大概被分派到多个线程中,以充实利用CPU,Reactor poll的巨细是固定的,根据CPU的数量确定。如果有过多的耗费CPU I/O的计算任务,可以提交到创建的ThreadPool线程池中专门处置处罚耗时的计算任务。
1、 muduo网络库实例

muduo网络库实质为: epoll + 线程池,优点是能够将网络I/O的代码和业务代码分开。 而业务代码主要分为:用户的连接和断开、用户的可读写变乱两类。至于什么时间发生这些变乱,由网络库进行上报,怎样监听这些变乱,都是网络库所封装好的,我们就可以快速进行项目开发。
muduo给用户提供了两个主要的类:
1、TcpServer:用于编写服务器步伐。
2、TcpClient:用于编写客户端步伐。
怎样配置muduo网络库请参考: 写文章-CSDN创作中心
 muduo网络库服务器编程

        基于muduo网络库开发服务器步伐

[*]组合TcpServer对象
[*]创建EventLoop变乱循环对象的指针
[*]明白TcpServer构造函数需要什么参数,输出ChatServer的参数
[*]在当前服务器类的构造函数当中,注册处置处罚连接的回调函数和处置处罚读写变乱的回调函数
#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>
#include <iostream>
#include <functional>
#include <string>
using namespace std;
using namespace muduo;
using namespace muduo::net;
using namespace placeholders;

class ChatServer
{
public:
    ChatServer(EventLoop *loop,
               const InetAddress &serverAddr,
               const string &nameArg)
      : _server(loop, serverAddr, nameArg), _loop(loop)
    {
      // 注册连接回调
      _server.setConnectionCallback(std::bind(&ChatServer::onConnection, this, _1));

      // 注册消息回调
      _server.setMessageCallback(std::bind(&ChatServer::onMessage, this, _1, _2, _3));

      // 设置线程数量
      _server.setThreadNum(4); // 4个IO线程
    }

    void start()
    {
      _server.start();
    }

private:
    // 处理连接
    void onConnection(const TcpConnectionPtr &conn)
    {
      if (conn->connected())
      {
            cout << conn->peerAddress().toIpPort() << " -> "
               << conn->localAddress().toIpPort() << " state : online " << endl;
      }
      else
      {
            cout << conn->peerAddress().toIpPort() << " -> " << conn->localAddress().toIpPort() << " state : offline " << endl;
      }
    }

    // 处理消息
    void onMessage(const TcpConnectionPtr &conn, Buffer *buffer, Timestamp time)
    {
      string buf = buffer->retrieveAllAsString();
      cout << "recv data: " << buf << " time: " << time.toString() << endl;
      conn->send(buf); // 回显消息
    }

    TcpServer _server;
    EventLoop *_loop;
};

int main()
{
    EventLoop loop;
    InetAddress addr("127.0.0.1", 9898); // 监听 127.0.0.1:9898
    ChatServer server(&loop, addr, "ChatServer");
    server.start(); // 启动服务器
    loop.loop();    // 事件循环
    return 0;
}          上面的代码简单的使用了muduo网络库实现了一个回显服务器,我们可以在linux系统终端中使用telnet下令让客户端连接。
2、muduo网络库原理

        Muduo 基于 Reactor 模式,焦点是变乱驱动。以下是其工作流程:
启动服务器:
        创建一个 EventLoop 实例作为主循环。
        创建一个 TcpServer 实例,设置回调函数(连接、消息处置处罚)。
        调用 loop.loop() 开始变乱循环。
变乱监听:
        主线程监听新连接。
        每当有新连接到来,将其分配到工作线程处置处罚。
变乱分发与处置处罚:
        EventLoop 监听变乱,通过 Poller 检测就绪的文件形貌符。
        调用 Channel 的回调函数处置处罚变乱。
数据收发与连接受理:
        使用 TcpConnection 提供的接口收发数据。
        在连接断开时,自动清算资源。
3、经典的服务器计划模式Reactor模式

        服务端步伐架构根本上是一个大的while循环,步伐壅闭在accept或poll函数上,等待被监控的socket形貌符上出现预期的变乱。变乱到达后,accept或poll函数的壅闭解除,步伐向下实行,根据socket形貌符上出现的变乱,实行read、write或错误处置处罚。
团体架构如下图所示:
https://i-blog.csdnimg.cn/direct/2b0a2607837440ddafe106a66e548649.png
        muduo的软件架构采用的也是Reactor模式,只是整个模式被分成多个类,而且支持以线程池的方式实现多线程并发处置处罚,以是显得有些复杂。团体架构如下图所示: 


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: muduo网络库2