网站开发制作心得,比较好看的网页设计,建设垂直网站需要哪些流程图,为什么不能进入wordpressmuduo网络库介绍
muduo网络库是陈硕大神开发的基于主从Reactor模式的#xff0c;事件驱动的高性能网络库。
网络编程中有很多是事务性的工作#xff0c;使用muduo网络库#xff0c;用户只需要填上关键的业务逻辑代码#xff0c;并将回调注册到框架中#xff0c;就可以实…muduo网络库介绍
muduo网络库是陈硕大神开发的基于主从Reactor模式的事件驱动的高性能网络库。
网络编程中有很多是事务性的工作使用muduo网络库用户只需要填上关键的业务逻辑代码并将回调注册到框架中就可以实现完整的网络服务。
muduo网络库的核心是one loop per thread thread pool有一个main Reactor负责accept连接然后将连接挂在某个sub Reactor中muduo通过round-robin算法选择一个sub Reactor。这样该连接的所有操作都由该sub Reactor进行处理多个连接可能被分派到多个线程中以充分利用CPU。
muduo采用的是固定大小的Reactor poll池的大小由用户进行设置通常所有Reactor的个数应该等于CPU的数目。这样程序的总体处理能力不会随连接数增加而下降。由于一个连接完全由一个线程管理那么请求的顺序性有保证突发请求也不会占满所有CPU。把IO分配个多给线程防止出现一个Reactor的处理能力饱和。
小规模计算可以在当前IO线程完成并发回结果从而降低响应的延迟。如果需要大规模计算可以再交给一个线程池让其进行处理从而防止阻塞当前sub Reactor导致响应变慢。
如果TCP连接有优先级之分可以将高优先级的连接放在一个单独的sub Reactor来处理从而避免优先级反转。
使用muduo实现echo服务器
由于网络库封装了网络IO代码所以不同的服务器的区别主要在于业务逻辑代码的不同。echo服务器简单地将来自客户端的数据回发给客户端应该是业务逻辑最简单的服务器了通过了解如何使用muduo网络库实现echo服务器有助于我们了解使用muduo网络库的基本方法如果需要对网络部分进行优化就需要深入源码了解muduo网络库的实现原理本文不详细涉及这部分以后可能会更新关于muduo源码剖析的博客。
使用muduo网络库我们需要组合TcpServer类一般还需要保存EventLoop指针。EventLoop负责管理事件循环epollTcpServer负责管理主ReactorAcceptor管理连接socket和从ReactorsEventLoopThreadPool管理客户端socket以及对于每种事件的回调这些回调会被合适的地方调用对应事件发生的时候。我们需要给TcpServer传入base loop、监听端口和IP地址一般是0.0.0.0、服务器名称打印日志并且设置各种事件的回调也就是在这里我们填入业务逻辑。 头文件EchoServer.h
// Copyright(C), Edward-Elric233
// Author: Edward-Elric233
// Version: 1.0
// Date: 2022/7/11
// Description:
#ifndef CHATSERVER_ECHOSERVER_H
#define CHATSERVER_ECHOSERVER_H#include muduo/net/TcpServer.h
#include muduo/net/EventLoop.h
#include muduo/net/InetAddress.h
#include muduo/net/TcpConnection.h
#include stringnamespace edward {class EchoServer {using TcpServer muduo::net::TcpServer;using EventLoop muduo::net::EventLoop;using InetAddress muduo::net::InetAddress;using TcpConnectionPtr muduo::net::TcpConnectionPtr;using Buffer muduo::net::Buffer;using Timestamp muduo::Timestamp;TcpServer tcpServer_;EventLoop *loop_;void onConnectionCallback(const TcpConnectionPtr conn);void onMessageCallback(const TcpConnectionPtr conn, Buffer* buffer, Timestamp timestamp);public:EchoServer(EventLoop *loop, const InetAddress address, const std::string name);void start();};}#endif //CHATSERVER_ECHOSERVER_H实现文件EchoServer.cpp
// Copyright(C), Edward-Elric233
// Author: Edward-Elric233
// Version: 1.0
// Date: 2022/7/11
// Description:
#include EchoServer.h
#include utils.h
#include functionalnamespace edward {using namespace std::placeholders;EchoServer::EchoServer(EventLoop *loop, const InetAddress address, const std::string name): tcpServer_(loop, address, name), loop_(loop) {//使用绑定器设置回调tcpServer_.setConnectionCallback(std::bind(EchoServer::onConnectionCallback, this, _1));tcpServer_.setMessageCallback(std::bind(EchoServer::onMessageCallback, this, _1, _2, _3));//根据本机的核数设置线程/Reactor数量如果不设置默认为1个tcpServer_.setThreadNum(std::thread::hardware_concurrency());
}//有新连接时的回调void EchoServer::onConnectionCallback(const TcpConnectionPtr conn) {if (conn-connected()) {} else {}}//连接上有消息到来时的回调void EchoServer::onMessageCallback(const TcpConnectionPtr conn, Buffer* buffer, Timestamp timestamp) {std::string msg buffer-retrieveAllAsString();print(conn-peerAddress().toIpPort(), :[, msg, ]at, timestamp.toFormattedString());conn-send(msg);}void EchoServer::start() {tcpServer_.start(); //使用epoll_ctl将连接socket放在loop上进行监听并设置对应的回调}}我们将回调都设置为成员函数这样做的好处是我们往往要在回调中访问其他系统资源成员函数可以访问数据成员避免传参。
测试文件test.cpp
#include EchoServer.h
void test_EchoServer() {muduo::net::EventLoop loop;edward::EchoServer echoServer(loop, muduo::net::InetAddress(6789), EchoServer);echoServer.start();loop.loop();return;
}测试结果 20220711 09:47:44.055888Z 26057 INFO TcpServer::newConnection [EchoServer] - new connection [EchoServer-0.0.0.0:6789#1] from 127.0.0.1:41678 - TcpServer.cc:80 127.0.0.1:41678 :[ Hello world ]at 20220711 09:47:49.515927 127.0.0.1:41678 :[ 123456 ]at 20220711 09:47:56.117636 20220711 09:47:57.069940Z 26057 INFO TcpServer::removeConnectionInLoop [EchoServer] - connection EchoServer-0.0.0.0:6789#1 - TcpServer.cc:109 结语
掌握了muduo网络基本的用法后就可以根据需要填充业务逻辑了如果想要了解更多就需要深入源码去了解啦。