QT:TCP/SOCKET 实现一个服务端与多个客户端通信,并识别是哪个客户端。--思路

QT 同时被 2 个专栏收录
1 篇文章 0 订阅
1 篇文章 0 订阅

QT:TCP/SOCKET 实现一个服务端与多个客户端通信,并识别是哪个客户端。–思路


可以制作一个座位槽,当做连入的客户端的位置。
想法图片:
想法图片
思维导图:
在这里插入图片描述
代码部分:
首先创建一个 座位槽 头文件

#ifndef CLIENTS_H
#define CLIENTS_H
#include <QtNetwork>
class CRSS_; //这里是防止循环导入头文件 
class clients:public QObject{
     Q_OBJECT
public:
    QTcpSocket *socket=nullptr; //客户端指针
    int location;  //座位
    QHostAddress address; //IP地址 
    CRSS_ *parent;  //服务端指针

    clients(CRSS_ *p,QTcpSocket *socket,int num);
    ~clients();
private:

private slots:
    void readMessages();
};
#endif // CLIENTS_H

然后 创建座位槽 源文件 实现方法

#include "clients.h"
#include "crss_.h"
clients::clients(CRSS_ *p,QTcpSocket *socket,int num){
    this->parent=p;
    this->socket=socket;
    this->location=num;
    this->address=socket->peerAddress();
}
clients::~clients(){

}

void clients::readMessages(){
    QString data=socket->readAll(); //读取客户端消息
    data=this->address.toString()+":"+data;
    qDebug()<<data; 
    parent->getMessage(data);  //传入服务端 处理消息函数
}

然后是 服务端 头文件

#ifndef CRSS__H
#define CRSS__H

#include <QDialog>
#include "clients.h"
namespace Ui {
class CRSS_;
}

class CRSS_ : public QDialog
{
    Q_OBJECT

public:
    explicit CRSS_(QWidget *parent = nullptr);
    ~CRSS_();
    QTcpServer *server; //服务端
    QTcpSocket *newClient; 

    int seats[600]; //座位号过滤变量
    clients *Clients[600]; //座位槽群
    int connect_num; //用于统计连接数
    void getMessage(QString str); //消息处理函数
    //(大家不用在意命名,后面可以就用这个处理消息,也可以另外再写一个消息处理函数把这个做中转传递函数)

private slots:
   void newConnected();  //当有客户端接入时执行的槽函数
    
    


private:
    Ui::CRSS_ *ui;
    void sendMessage(QString msg,int loction); // 发送消息 
    void send_live_Message(QString msg,QTcpSocket *socket);
    int check_client_s(); //查看空闲座位槽
};

#endif // CRSS__H

接下来是服务端的源文件

#include "crss_.h"
#include "ui_crss_.h"
#include "QPainter"
#include "QMouseEvent"
#include "QGraphicsDropShadowEffect"
#include "wx_d.h"
#include "get_Message.h"
CRSS_::CRSS_(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::CRSS_)
{
    ui->setupUi(this);
    
    server=new QTcpServer();
    if(!server->listen(QHostAddress::LocalHost,6666)){
        qDebug()<<server->errorString();
        close();
    }else{
        qDebug()<<"TCP服务开通成功";
        ui->connect_state->setText("服务端通信状态: 正常");
    }
    connect(server,SIGNAL(newConnection()),this,SLOT(newConnected()));


}

CRSS_::~CRSS_()
{
    delete ui;
}


int CRSS_::check_client_s(){
    for (int i=1;i<=255;i++) {
        if(seats[i]==NULL)
            return i;
    }
    return 0;
}

void CRSS_::newConnected(){
    newClient=server->nextPendingConnection();
    qDebug()<<"有新连接尝试接入";
    int loaction=check_client_s();
    if(loaction==0){
        send_live_Message("服务器已满,请稍后再连接",newClient);
        newClient->disconnectFromHost();
        qDebug()<<"服务器已满,已阻止连接接入";
        return;
    }
    connect_num++;
    ui->connect_num->setText("连接数: "+QString::number(connect_num));
    clients *client=new clients(this,newClient,loaction);

    //座位槽识别变量
    seats[loaction]=1;
    //存入座位槽
    Clients[loaction]=client;
    connect(Clients[loaction]->socket,SIGNAL(readyRead()),Clients[loaction],SLOT(readMessages()));

}
void CRSS_::send_live_Message(QString msg,QTcpSocket *socket){
    std::string str=msg.toStdString();
    const char * data=str.c_str();
    socket->write(data);
}
void CRSS_::sendMessage(QString msg,int loction){
    std::string str=msg.toStdString();
    const char *data=str.c_str();
    Clients[loction]->socket->write(data);
}
void CRSS_::getMessage(QString str){
    QString nowMessage=ui->label->text();

    ui->label->setText(nowMessage+"\n"+str);
}


效果图:
未连接前
效果图1
连接后:
效果图2


结语:
额。。。大家不用在意这个 电脑维修提交系统

这是我学习途中 写项目做的 正好遇到这个的问题 所以自己捣鼓了大半天才想出来这个思路。

抱歉 本人自学QT 没多久 代码并不是很精通
有什么问题或者可以优化的地方
大佬们可以说一下,我也可以学习一下


  • 3
    点赞
  • 1
    评论
  • 20
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

评论 1 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页

打赏作者

SSHLQ_JOKER

各位大佬可怜可怜网络乞丐吧

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值