
目录1Muduo库的说明2Muduo库的主要组件3Muduo常用的类接口4Muduo库的代码运用5、Muduo库的工作流程6、特点与优势1Muduo库的说明Muduo库是一个基于非阻塞IO和IO多路复用的C高并发TCP网络编程库底层使用底层使用 epoll 模型的IO多路复用。它基于Reactor模式实现一个事件监听器监听所有事件当对应的IO事件到来时分发器将事件分发给对应的事件处理器处理并支持多线程并发处理的网络库使用的线程模型是one loop per thread一个线程对应一个事件处理模块。注意Reactor模式和one loop per thread模型请在此连接下观看Reactor模式2Muduo库的主要组件1TCPServer类该类用于创建和管理TCP服务器。用户可以通过TcpServer设置连接建立、消息到达等事件的回调处理函数。2EventLoop类事件循环对象负责监听和处理事件它是一个真正进行事件监控的类。事件循环是Muduo库的核心组件每个线程线程都有一个独立的EventLoop对象即事件循环。事件循环负责监听文件描述符的事件如可读、可写等它包含了一个事件队列和事件处理函数。当事件发生时EventLoop会将事件放入队列中并依次调用相应的事件回调函数来处理这些事件。TCPServer通过创建多个EventLoop来充分利用多核CPU的并行处理能力。3TcpConnection类它代表了一个TCP连接封装了与特定客户端的所有交互包括数据的发送和接收、连接的建立和断开等。在连接建立时TcpConnection会设置相关的回调函数进行事件的监听。在连接维护阶段TcpConnection会处理读接收事件和写发送事件确保数据的正确传输。在连接关闭时TcpConnection会触发相关的回调函数处理连接关闭时的清理工作。4TcpClient类一个用于管理TCP客户端连接的重要组件。TcpClient类主要负责发起TCP连接并在连接建立后管理这个连接。当连接建立成功后TcpClient会创建一个TcpConnection对象通过回调函数来管理这个连接。5Buffer类它是一个高效的数据缓冲区用于存储从网络中接收到的数据以及待发送的数据。当创建该类对象时我们可以通过调用Buffer类的读写接口来向缓冲区中写入数据和从缓冲区中读取数据。在读写过程中Buffer类会自动处理内存分配、扩容和回收等底层细节。3Muduo常用的类接口1TCPServer类接口// 用于设置线程池中线程的数量即设置reactor线程数量// 默认情况下只有一个reactor线程即主线程它即获取新连接又处理IO事件void setThreadNum(int numThreads);// 启动服务器开始监听指定的端口准备接受客户端的连接。void start();// 设置连接建立或关闭时的回调函数该回调函数会在有新的连接建立或现有连接断开时被调用。其中该回调函数自定义设置且该回调函数接受一个const TcpConnectionPtr 参数代表连接对象。TcpConnectionPtr定义为typedef std::shared_ptrTcpConnection TcpConnectionPtr;下面信息处理的回调函数同理void setConnectionCallback(const ConnectionCallback cb);自定义函数cp如void cp(const muduo::net::TcpConnectionPtr conn);// 设置消息处理的回调函数收到新连接消息时回调函数被调用。其中该回调函数自定义设置它接受三个参数一个const TcpConnectionPtr代表连接对象一个Buffer*包含接收到的数据以及一个Timestamp数据到达的时间戳这里我们不用管。void setMessageCallback(const MessageCallback cb);自定义函数cb如void onMessage(const muduo::net::TcpConnectionPtr conn, muduo::net::Buffer *buf, muduo::Timestamp)2EventLoop类接口// 开始事件监控循环使EventLoop对象开始监听和处理各种事件。void loop();// 退出事件的监控循环void quit();// 在指定的时间点执行一个回调函数 这个回调函数用于在将来的某个确切时间点调度一次性的任务对象。runAfter和runEvery的回调函数同理。TimerId runAt(Timestamp time, TimerCallback cb);// 设置一个延时定时器在指定延迟多少delay毫秒后执行回调函数cb。TimerId runAfter(double delay, TimerCallback cb);// 设置一个周期性定时器每隔指定的时间间隔执行回调函数cb。TimerId runEvery(double interval, TimerCallback cb);// 取消定时器。void cancel(TimerId timerId);3TcpConnection类接口// 发送数据messagevoid send(string message);void send(const void* message, int len);void send(const StringPiece message);void send(Buffer* message);// 判断当前连接是否连接正常bool connected() const// 关闭连接void shutdown();4TcpClient类接口// 连接服务器该接口是非阻塞接口。// 通常为了保证连接之间的同步工作客户端还需要借助一个CountDownLatch类该类通过计数器将线程阻塞等待且是线程安全。void connect();// 关闭连接void disconnect();// 获取客户端对应的TcpConnect连接。由于connect接口是非阻塞操作所以当发起connect后有可能还没有成功建立连接TcpConnectionPtr connection() const;// 注意由于客户端也是通过EventLoop类进行IO事件的处理所以客户端这里也运用setConnectionCallback和setMessageCallback函数// 连接服务器成功或连接关闭时的回调函数void setConnectionCallback(ConnectionCallback cb);// 收到服务器发送的消息时的回调函数void setMessageCallback(MessageCallback cb);5Buffer类接口// 获取缓冲区可读数据大小size_t readableBytes() const;// 获取缓冲区中数据的起始地址const char* peek() const;// 从缓冲区中预览4字节数据但并不从缓冲区删除。网络数据报中通常前4字节表示数据的长度。这个方法通常用于在解析网络协议时通过前四字节检查数据是否完整或合格。int32_t peekInt32() const;// 数据读取位置向后偏移4字节本质上就是删除起始位置的4字节数据void retrieveInt32();// peekInt32和retrieveInt32功能的合并即先运行peekInt32再运行retrieveInt32int32_t readInt32();// 从缓冲区取出所有数据作为string返回并删除缓冲区中的数据string retrieveAllAsString();// 从缓冲区取走len长度的数据作为string返回并删除缓冲区中的数据string retrieveAsString(size_t len);4Muduo库的代码运用这里我们基于muduo库来实现一个简单英译汉服务器和客户端。具体代码请在此链接下观看基于Muduo的英译汉服务的实现5、Muduo库的工作流程用户创建TcpServer对象并设置连接建立、消息到达等事件的回调处理函数。TcpServer启动后会创建一个EventLoop对象和一个线程池。主线程运行一个baseLoop即EventLoop的一个实例负责监听新的连接请求。当有新的客户端连接请求到来时baseLoop会调用TcpServer设置的连接建立回调处理函数将连接请求分发给子线程处理。子线程接收到连接请求后会创建一个TcpConnection对象来处理该连接的具体事件如读、写、关闭等。TcpConnection将读、写、关闭等操作与回调处理函数绑定在一起并调用EventLoop的相应方法来处理这些事件。底层事件循环中主线程只执行监听操作与用户回调而子线程则具体执行操作。6、特点与优势高性能Muduo库采用了非阻塞IO和事件循环的设计能够充分利用多核CPU的性能实现高效的网络通信。稳定性Muduo库采用了基于Reactor模式的事件处理机制即避免了传统多线程模型中的线程竞争和同步问题又实现了高效率的网络通信。