当前位置: 代码迷 >> 综合 >> muduo echo服务器测试
  详细解决方案

muduo echo服务器测试

热度:88   发布时间:2023-12-25 07:34:47.0

echo 服务器测试

    • 调试文件
    • task.json

/*muduo网络库给用户提供了两个主要的类TCPServer:用于编写服务器程序TCPClient:用于编写客户端程序epoll+线程池好处:能够把网络I/O的代码和业务代码区分开,主要开发业务,网络库代码封装了业务代码暴漏:1。用户的连接和断开2.用户可读写事件 */
#include<muduo/net/TcpServer.h>
#include<muduo/net/EventLoop.h>
#include<string>
#include<iostream>
#include<functional>
using namespace muduo;
using namespace muduo::net;
using namespace std;//基于muduo网络库开发服务器程序
/*1.组合TcpServer对象2.创建EventLoop事件循环对象的指针3.明确TcpServer构造函数需要什么参数,输出ChatServer的构造函数4.在当前服务器类的构造函数中,注册处理链接的回调函数和处理读写事件的回调函数5.设置合适的服务端线程数量,muduo库会自己划分I/O和woker线程 */
class ChatServer
{
    
public:ChatServer(EventLoop* loop, const InetAddress& listenAddr,const string& nameArg):_server(loop,listenAddr,nameArg),_loop(loop){
    //将网络代码和业务代码区分开//普通函数 我知道这个函数就要在这里发生,也知道会发生什么(在什么地方发生,在发生之后怎么做)//给服务器注册用户连接创建和断开回调(回调 模块解耦的重点)//知道了该怎么做,但是不知道什么时候会发生,对端发送消息才知道用户连接的创建和断开,数据读写请求,网络库来监听,接听到对端发送的业务请求,注册回调,相应的事件发生后,帮我们调用相应的回调函数,在回调中开发业务//连接的创建和断开 setConnectionCallback 返回值<void (const TcpConnectionPtr&) 没有返回值,一个成员变量//消息的读写的事件 setMessageCallback //成员方法自带this指针,使用绑定器处理问题,底层监听到就会帮我们调用_server.setConnectionCallback(std::bind(&ChatServer::onConnection,this,_1));//给服务器注册用户读写事件回调_server.setMessageCallback(std::bind(&ChatServer::onMessage,this,_1,_2,_3));//设置服务端的线程数量 1个I/O 3个工作线程_server.setThreadNum(4);}//开启事件循环void start(){
    _server.start();}
private://专门处理用户的连接创建和断开 (自行在muduo库上注册了)//从epoll拿来事件 listenfd 从listenfd上accept表示有新用户连接 拿出来一个和socket专门和用户通信//当有新用户创建或者原来连接用户断开连接,这个方法就会响应void onConnection(const TcpConnectionPtr& conn){
    //是否连接成功//toip 打印ip toport 打印端口if(conn->connected()){
    //对端地址信息cout << conn->peerAddress().toIpPort() << "->" << conn->localAddress().toIpPort() << "STATE :online" <<endl;}else{
    cout << conn->peerAddress().toIpPort() << "->" << conn->localAddress().toIpPort() << "STATE :offline" <<endl;//相当于close 释放 socket资源conn->shutdown();//连接断开,回收资源_loop->quit();}}//专门处理用户读写事件void onMessage(const TcpConnectionPtr& conn,Buffer* buffer,Timestamp time){
    /*1.第一个参数是连接,可以通过它读写数据2.缓冲区3.接收到数据的时间细节*///把接收到的全部数据放到字符串中string buf = buffer->retrieveAllAsString();cout << "recv data" << buf << "Time:" << time.toString() << endl;conn->send(buf);}TcpServer _server;  //#1 对象需要构造,不指定构造就需要默认构造,没有默认构造,不指定相应的构造就无法创建对象/*参数有四个 1.事件循环EventLoop, EventLoop* loop 事件循环Reactor反应堆2.绑定的IP地址和端口号, const InetAddress& listenAddr IP地址加端口3.给TcpServer一个名字, const string& nameArg 服务器的名字,给线程绑定名字4.TCP协议的选项 Option option = kNoReusePort */EventLoop* _loop;   //#2 保存事件循环 操作epoll
};int main()
{
    EventLoop loop;InetAddress addr("127.0.0.1",6000);ChatServer server(&loop,addr,"Charserver");//listenfd 将epoll_ctl添加到epoll上server.start();//epoll_wait 以阻塞方式等待新用户连接,已连接用户的读写事件loop.loop();return 0;
}

调试文件

ctrl+shift+b

task.json

{
    "tasks": [{
    "type": "shell","label": "g++ build active file","command": "/usr/bin/g++","args": ["-g","-std=c++11","${file}","-o","${fileDirname}/${fileBasenameNoExtension}","-lmuduo_net","-lmuduo_base","-lpthread"],"options": {
    "cwd": "/usr/bin"},"problemMatcher": ["$gcc"],"group": "build"}],"version": "2.0.0"
}
  相关解决方案