ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

muduo echo服务器测试

2021-02-10 13:01:07  阅读:266  来源: 互联网

标签:muduo const EventLoop 用户 echo 服务器 连接 loop


echo 服务器测试

/*
    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"
}

标签:muduo,const,EventLoop,用户,echo,服务器,连接,loop
来源: https://blog.csdn.net/qq_38684512/article/details/113781190

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有