分类信息网站建设系统,在上海注册公司需要多少钱,电影网站页面seo,外贸网站建设和seo今天来介绍集群聊天器项目中网络模块代码的核心模块——muduo网络库#xff0c;一起来看看吧~ 环境搭建C项目——集群聊天服务器项目(一)项目介绍、环境搭建、Boost库安装、Muduo库安装、Linux与vscode配置-CSDN博客
Json第三方库C项目——集群聊天服务器项目(二)Json第三方库…今天来介绍集群聊天器项目中网络模块代码的核心模块——muduo网络库一起来看看吧~ 环境搭建C项目——集群聊天服务器项目(一)项目介绍、环境搭建、Boost库安装、Muduo库安装、Linux与vscode配置-CSDN博客
Json第三方库C项目——集群聊天服务器项目(二)Json第三方库-CSDN博客
一、muduo网络库介绍
muduo由陈硕大佬开发是一个基于非阻塞IO和事件驱动的C高并发TCP网络库
网络设计reactors in threads - one loop per thread
one loop per thread指的是
1一个线程只能有一个事件循环EventLoop
2一个文件描述符只能由一个线程进行读写即一个TCP连接必须归属于某个EventLoop管理。
方案的特点是one loop per thread有一个main reactor负载accept连接然后把连接分发到某个sub reactor该连接的所用操作都在那个sub reactor所处的线程中完成。
多个连接可能被分派到多个线程中以充分利用CPU。 Reactor poll的大小是固定的根据CPU的数目确定。
原理一个Base IO thread负责accept新的连接接收到新的连接以后使用轮询的方式在reactor pool中找到合适的sub reactor将这个连接挂载上去这个连接上的所有任务都在这个sub reactor上完成。
如果有过多的耗费CPU I/O的计算任务可以提交到创建的ThreadPool线程池中专门处理耗时的计算任务。
将epoll和线程池封装起来好处是能够把网络的I/O代码与业务代码区分开
二、muduo网络库主要的类
TcpServer:用于编写服务器程序的类
TcpClient:用于编写客户端程序的类
接下来使用muduo网络库开发一个基本的服务器程序 三、基于muduo网络库开发服务器程序
3.1 基本步骤
1.组合TcpServer对象
2.创建EventLoop事件循环对象的指针
3.明确TcpServer构造函数需要什么参数输出ChatServer的构造函数
4.在当前服务器类的构造函数中注册处理连接和读写事件的回调函数
5.设置合适的服务端线程数量muduo会自动划分I/O线程和worker线程
3.2 代码 头文件
#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;组合TcpServer对象
创建EventLoop事件循环对象的指针
明确TcpServer构造函数需要什么参数
class ChatServer
{
public:ChatServer(EventLoop* loop, //事件循环——Reactor反应堆const InetAddress listenAddr, //IP和端口const string nameArg) //服务器的名字: _server(loop, listenAddr, nameArg), _loop(loop){}
private:TcpServer _server;EventLoop *_loop; //epoll
};
输出ChatServer的构造函数
构造函数负责给服务器注册用户连接与断开回调函数注册读写事件回调函数并设置线程数量muduo网络库会自动分配线程用于主reactor和子reactor ChatServer(EventLoop* loop, //事件循环——Reactor反应堆const InetAddress listenAddr, //IP和端口const string nameArg) //服务器的名字: _server(loop, listenAddr, nameArg), _loop(loop){//给服务器注册用户连接的创建和断开回调_server.setConnectionCallback(std::bind(ChatServer::OnConnection,this,_1));//给服务器注册用户读写事件回调_server.setMessageCallback(std::bind(ChatServer::OnMessage,this,_1,_2,_3));//设置服务器的线程数量 1 I/O线程3个worker线程_server.setThreadNum(4);}
开启时间循环函数 //开启事件循环void start(){_server.start();}连接与断开回调函数显示上线和下线 //专门处理用户连接创建和断开 epollvoid OnConnection(const TcpConnectionPtrconn){if(conn-connected()){cout conn-peerAddress().toIpPort() - conn-localAddress().toIpPort() state:online endl;}else{cout conn-peerAddress().toIpPort() - conn-localAddress().toIpPort() state:offline endl;conn-shutdown();}}
读写事件回调函数这里的功能是将客户端发来的信息发回去 //专门处理用户读写事件 void OnMessage(const TcpConnectionPtrconn , //连接Buffer*buffer, //缓冲区Timestamp time) //接受到数据的时间信息{ string buf buffer-retrieveAllAsString();cout recv data : buf time: time.toString() endl;conn-send(buf);}
main函数
int main(){EventLoop loop; //epollInetAddress addr(127.0.0.1,6000);ChatServer server(loop,addr,ChatServer);server.start(); loop.loop(); //epoll_wait以阻塞方式等待新用户连接或读写事件等return 0;}
全部代码
/*muduo网络库给用户提供了两个主要的类
TcpServer:用于编写服务器程序的类
TcpClient:用于编写客户端程序的类将epoll和线程池封装起来好处是能够把网络的I/O代码与业务代码区分开
*/#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;/*基于muduo网络库开发服务器程序
1.组合TcpServer对象
2.创建EventLoop事件循环对象的指针
3.明确TcpServer构造函数需要什么参数输出ChatServer的构造函数
4.在当前服务器类的构造函数中注册处理连接和读写事件的回调函数
5.设置合适的服务端线程数量muduo会自动划分I/O线程和worker线程
*/
class ChatServer
{
public:ChatServer(EventLoop* loop, //事件循环——Reactor反应堆const InetAddress listenAddr, //IP和端口const string nameArg) //服务器的名字: _server(loop, listenAddr, nameArg), _loop(loop){//给服务器注册用户连接的创建和断开回调_server.setConnectionCallback(std::bind(ChatServer::OnConnection,this,_1));//给服务器注册用户读写事件回调_server.setMessageCallback(std::bind(ChatServer::OnMessage,this,_1,_2,_3));//设置服务器的线程数量 1 I/O线程3个worker线程_server.setThreadNum(4);}//开启事件循环void start(){_server.start();}private://专门处理用户连接创建和断开 epollvoid OnConnection(const TcpConnectionPtrconn){if(conn-connected()){cout conn-peerAddress().toIpPort() - conn-localAddress().toIpPort() state:online endl;}else{cout conn-peerAddress().toIpPort() - conn-localAddress().toIpPort() state:offline endl;conn-shutdown();}}//专门处理用户读写事件 void OnMessage(const TcpConnectionPtrconn , //连接Buffer*buffer, //缓冲区Timestamp time) //接受到数据的时间信息{ string buf buffer-retrieveAllAsString();cout recv data : buf time: time.toString() endl;conn-send(buf);}TcpServer _server;EventLoop *_loop; //epoll
};int main(){EventLoop loop; //epollInetAddress addr(127.0.0.1,6000);ChatServer server(loop,addr,ChatServer);server.start(); loop.loop(); //epoll_wait以阻塞方式等待新用户连接或读写事件等return 0;}
3.3 服务器程序执行
3.3.1 g编译
g -o server muduo_server.cpp -lmuduo_net -lmuduo_base -lpthread
终端输入上述语句其中g -I头文件搜索路径 -L库文件搜素路径 -l库名称执行server文件结果如下 可以看到客户端登录成功后信息成功回显
telnet 127.0.0.1 60003.3.2 CMake编译
可以查看Linux环境下是否有CMake有muduo库其实就已经有CMake了通过下面的命令查看版本号
cmake -version 在3.2文件的同级目录下创建CMakeLists.txt文件分别写出编译选项、需要编译的源文件列表、可执行文件存储的路径、生成可执行文件、以及链接的库文件
cmake_minimum_required(VERSION 3.0)
project(main)# 配置编译选项
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g) # 可调试可执行文件#配置头文件搜索路径
# include_directories()#配置库文件搜索路径
# link_directories()# 设置需要编译的源文件列表
set(SRC_LIST ./muduo_server.cpp)
# 设置可执行文件存储的路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)# 把.指定路径下的所有源文件放入SRC_LIST变量名中
# aux_source_directory(.SRC_LIST)# 表示生成可执行文件server由SRC_LIST变量定义的源文件而来
add_executable(server ${SRC_LIST}) # 生成可执行文件#表示server这个目标程序需要链接muduo_net muduo_base pthread库文件
target_link_libraries(server muduo_net muduo_base pthread)
可以看到这里将可执行文件放在了项目文件的bin文件夹下执行server文件同样回显相同的结果 至此muduo网络库的示例代码与实验完毕期待后续项目的更新把~