muduo网络库的通信使用(包括客户端和服务端)

3 篇文章 2 订阅
该代码示例展示了如何使用muduo库创建一个简单的TCP服务器和客户端。服务器监听指定端口,接收到exit或quit命令时关闭连接,其他数据转发至Qt信号。客户端连接到服务器并发送数据,接收到的数据通过Qt信号发送。
摘要由CSDN通过智能技术生成
/**********************server start*********************/
//server.h
#ifndef SERVER_H
#define SERVER_H

#include <QThread>
#include <QDebug>

#include "muduo/base/Logging.h"
#include "TcpServer.h"
#include "EventLoop.h"
#include "InetAddress.h"
#include <functional>
#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <iostream>

using namespace muduo;
using namespace muduo::net;
using namespace std;


class Server : public QThread
{
    Q_OBJECT
public:
    explicit Server();


    void run()override;

    void Start(int port=8080);
    void Stop();

    void Send(string data);

    void onConnection(const TcpConnectionPtr& conn);
    void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp time);

signals:
    void cppSigRecv(QString data);
public slots:

private:
    EventLoop* loop_ = nullptr;
    TcpServer *server_ = nullptr;
    int port;
};


//server.cpp
#include "server.h"

Server::Server()
{
}

void Server::onConnection(const TcpConnectionPtr &conn)
{
    qDebug() << conn->peerAddress().toIpPort().c_str() << " -> "
             << conn->localAddress().toIpPort().c_str() << " is "
             << (conn->connected() ? "UP" : "DOWN");
    //conn->send("hello calm\n");
}

void Server::onMessage(const TcpConnectionPtr &conn, Buffer *buf, Timestamp time)
{
    string msg(buf->retrieveAllAsString());
    //LOG_INFO << conn->name() << " recv " << msg.size() << " bytes at " << time.toString();
    LOG_INFO << "server recv: " << msg;
    if (msg == "exit\n")
    {
        conn->send("bye\n");
        conn->shutdown();//关闭写端
    }
    else if (msg == "quit\n")
    {
        loop_->quit();
    }
    else
        emit cppSigRecv(QString::fromStdString(msg));
    //conn->send(msg);
}

void Server::run()
{
    qDebug() << "run";

    loop_ = new EventLoop();
    InetAddress serverAddr("0.0.0.0", port);

    server_ = new TcpServer(loop_, serverAddr, "Server");

    //给服务器注册用户建立断开连接的回调
    server_->setConnectionCallback(std::bind(&Server::onConnection,this,std::placeholders::_1));
    //给服务器注册用户可读写事件回调
    server_->setMessageCallback(std::bind(&Server::onMessage,this,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3));

    //server_->setThreadNum(3);
    server_->start();
    loop_->loop();

    LOG_INFO << "exit";
}

void Server::Start(int port)
{
    this->port = port;
    start();
}

void Server::Stop()
{
    if(loop_)
        loop_->quit();
}

void Server::Send(string data)
{
    std::map<string, TcpConnectionPtr> map = server_->connection();
    std::map<std::string, TcpConnectionPtr>::iterator it;
   for (it = map.begin(); it != map.end(); it++)
   {
       LOG_INFO << it->first;
       it->second->send(data);
   }
}
/*********************server end*******************************/

/*********************client end*******************************/
//.h
#ifndef CLIENT_H
#define CLIENT_H

#include <QThread>
#include <QDebug>
#include "muduo/base/Logging.h"
#include "muduo/net/EventLoop.h"
#include "muduo/net/InetAddress.h"
#include "muduo/net/TcpClient.h"

#include <utility>

#include <stdio.h>
#include <unistd.h>
#include <iostream>

using namespace muduo;
using namespace muduo::net;
using namespace std;

class Client : public QThread
{
    Q_OBJECT
public:
    Client();
#if 0
    Client(EventLoop* loop, const InetAddress& listenAddr)
    : loop_(loop),
      client_(new TcpClient(loop, listenAddr, "Client"))
  {
    client_->setConnectionCallback(
        std::bind(&Client::onConnection, this, _1));
    client_->setMessageCallback(
        std::bind(&Client::onMessage, this, _1, _2, _3));
    // client_.enableRetry();
  }
#endif
  void connect()
  {
        client_->connect();
  }

  void Start(string ip="127.0.0.1", int port=8080);
  void Stop();

  void Send(string data);
signals:
  void cppSigRecv(QString data);
private:
    void onConnection(const TcpConnectionPtr& conn);
    void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp receiveTime);
    void run()override;

    EventLoop* loop_ = nullptr;
    TcpClient *client_ = nullptr;
    string ip;
    int port;
};
#endif // CHARGENCLIENT_H


//client.cpp
#include "client.h"

Client::Client()
{

}

void Client::onConnection(const TcpConnectionPtr& conn)
{
    cout << conn->localAddress().toIpPort() << " -> "
             << conn->peerAddress().toIpPort() << " is "
             << (conn->connected() ? "UP" : "DOWN") << endl;

    if (!conn->connected())
        loop_->quit();
}

void Client::onMessage(const TcpConnectionPtr &conn, Buffer *buf, Timestamp receiveTime)
{
    //buf->retrieveAll();

    string msg(buf->retrieveAllAsString());
    //LOG_INFO << conn->name() << " recv " << msg.size() << " bytes at " << time.toString();
    std::cout << "clent receive: " << msg  << endl;

    emit cppSigRecv(QString::fromStdString(msg));
}

void Client::run()
{
    qDebug() << "run";

    loop_ = new EventLoop();
    InetAddress serverAddr(ip, port);

    client_ = new TcpClient(loop_, serverAddr, "Client");

    client_->setConnectionCallback(std::bind(&Client::onConnection, this, _1));
    client_->setMessageCallback(std::bind(&Client::onMessage, this, _1, _2, _3));

    client_->connect();
    loop_->loop();

    qDebug() << "exit";
}

void Client::Start(string ip, int port)
{
    this->ip = ip;
    this->port = port;

    start();
}

void Client::Stop()
{
    if(loop_)
        loop_->quit();
}

void Client::Send(string data)
{
    client_->connection()->send(data);
}
#endif // SERVER_H

运行效果如下:
在这里插入图片描述
在这里插入图片描述
源码地址:点击跳转

觉得有帮助的话,打赏一下呗。。
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值