20230904 QT客户端服务器搭建聊天室

2023-11-05

Ser

cpp
=================================================================
#include "app.h"
#include "ui_app.h"

APP::APP(QWidget *parent):QWidget(parent),ui(new Ui::APP)
{
    ui->setupUi(this);
    this->resize(550,400);

    ui->Line->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中
    ui->Line->setFont(QFont("楷体",10));
    ui->LB1->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中
    ui->LB1->setFont(QFont("楷体",13));
    //ui->Listw->setFont(QFont("楷体",8));
    ui->SB1->setFont(QFont("华文行楷",15));

    server = new QTcpServer(this); //创建服务器server

}

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

//Start服务器按钮对应的槽函数
void APP::on_SB1_clicked()
{
    //获取UI界面的port号
    quint16 port = ui->Line->text().toUInt();

   //服务器设定为监听状态
   //bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any,quint16 port = 0)
   //参数1:监听的主地址,any=>所有的;也可给定特定的地址进行监听
   //参数2:通过指定的端口号进行访问服务器,若为0,则表示由服务器自动分配,若非0则表示指定端口号
   //返回值,成功<=true;失败<=false;
    if(!server->listen(QHostAddress::Any,port))
    {
        QMessageBox::critical(this,"失败","Server启动失败");
        return;
    }
    else
    {
        QMessageBox::about(this,"成功","启动成功");
    }

    //Server启动成功,对客户端进行监听
    //有客户端发送来的链接请求,服务器会自动发送一个newConenction信号
    //将该信号连接到对应的槽函数中处理相关逻辑
    connect(server,&QTcpServer::newConnection,this,&APP::newConnection_slot);



}
void APP::newConnection_slot()//处理newConnection信号的槽函数的实现
{
    qDebug() <<"Cli连接了请求了";

    //获取最新链接的客户端套接字
    //原型 [virtual] QTcpsocket *QTcpseicer::nextPendingConnection()
    //参数:无
    //返回值:最新链接客户端套接字的指针
    QTcpSocket *s = server->nextPendingConnection();

    clientList.push_back(s);//将获取到的套接字存放到客户端的容器中

    //此时已经链接上客户端了
    //如果该套接字有数据数据项服务器发送过来,则该套接字就会自动发射一个readyRead信号
    //用该信号处理相关函数
    connect(s,&QTcpSocket::readyRead,this,&APP::readyRead_slot);
}

void APP::readyRead_slot()//关于readyRead信号对应的槽函数
{
    //排除客户端链表中无效的客户端套接字
    for(int i=0;i<clientList.count();i++)
    {
        //判断套接字状态
        //原型:SocketState state() const
        //功能:返回客户端套接字状态
        //参数:无
        //返回值:客户端的状态,若结果为,则表示未链接
        if(clientList[i]->state() == 0)
        {
            clientList.removeAt(i);//若为,则removed掉
        }

    }

    //便利所有的客户端查看哪个客户端发来的数据
    for(int i=0;i<clientList.count();i++)
    {
        //原型:qint64 bytesAvailiable() const override
        //功能:返回客户端套接字中可读的字节个数
        //参数:无
        //返回值:当前客户端的可读的字节个数,若结果为,则表示无数据可读
        if(clientList[i]->bytesAvailable() != 0)
        {
            //读取当前客户端的相关数据
            //原型:QByteArray readAll()
            //功能:读取当前套接字中的所有数据,返回一个字节数组
            //参数:无
            //返回值:返回的字节数组
            QByteArray msg = clientList[i]->readAll();

            //数据=>UI界面上
            ui->Listw->addItem(QString::fromLocal8Bit(msg));

            //接收到的消息,发送给所有的客户端
            for(int j=0;j<clientList.count();j++)
            {
                clientList[j]->write(msg);
            }
        }

    }
}
.h
=================================================================
#ifndef APP_H
#define APP_H
//头文件
#include <QWidget>
#include <QTcpServer>//服务器
#include <QTcpSocket>//客户段
#include <QList>//链表   存放客户端的容器
#include <QDebug>
#include <QMessageBox>//消息



QT_BEGIN_NAMESPACE
namespace Ui { class APP; }
QT_END_NAMESPACE

class APP : public QWidget
{
    Q_OBJECT

public:
    APP(QWidget *parent = nullptr);
    ~APP();

    //QList<QTcpServer *> clientList;

private slots:
    void on_SB1_clicked();
    void newConnection_slot();
    void readyRead_slot();

private:
    Ui::APP *ui;

    QTcpServer *server;
    QList<QTcpSocket *> clientList;
};
#endif // APP_H

T1.pro
=================================================================
QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    app.cpp

HEADERS += \
    app.h

FORMS += \
    app.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
mian.cpp
=================================================================
#include "app.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    APP w;
    w.show();
    return a.exec();
}

Cli

cpp
=================================================================
#include "cli.h"
#include "ui_cli.h"

Cli::Cli(QWidget *parent):QWidget(parent),ui(new Ui::Cli)
{
    ui->setupUi(this);
    socket = new QTcpSocket(this);//客户端指针实例化空间
    ui->USER->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中
    ui->USER->setFont(QFont("楷体",10));
    ui->USERed->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中
    ui->USERed->setFont(QFont("楷体",10));
    ui->IP->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中
    ui->IP->setFont(QFont("楷体",10));
    ui->IPed->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中
    ui->IPed->setFont(QFont("楷体",10));
    ui->PORT->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中
    ui->PORT->setFont(QFont("楷体",10));
    ui->PORTed->setAlignment(Qt::AlignCenter);//标签文本对齐方式 居中
    ui->PORTed->setFont(QFont("楷体",10));
    ui->msged->setFont(QFont("等线",10));
    ui->connectSB1_2->setFont(QFont("华文行楷",15));
    ui->disconnectSB2_2->setFont(QFont("华文行楷",15));
    ui->sendSB3->setFont(QFont("华文行楷",15));

    //connect(ui->connectSB1_2,&QPushButton::clicked,this,&Cli::readyRead_slot);

    //如果链接Server成功(只链接一次),客户端就会发射一个connected的信号,将该信号链接槽函数
    connect(socket,&QTcpSocket::connected,this,&Cli::connect_slot);

    //客户端与服务器链接成功后,若服务器向客户端发送来数据,则客户端就会自动发射一个readyRead信号
    //Ser<=>Cli,if(Ser=>),CLi=>readyRead
    connect(socket,&QTcpSocket::readyRead,this,&Cli::readyRead_slot);

    //客户端与服务器链接成功后,客户端就会自动发射一个disconnected信号
    connect(socket,&QTcpSocket::disconnected,this,&Cli::disconnected_slot);
}

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


void Cli::on_connectSB1_2_clicked()
{
    //userName = ui->USERed->text();//get USER
    QString s1 = "八嘎";
    userName = s1;
    //QString hostName = ui->IPed->text();//get IP
    QString s2 = "192.168.124.72";
    QString hostName = s2;
    quint16 port = ui->PORTed->text().toUInt();//get PORT

    qDebug() << "获取信息-----";
    //链接主机
    socket->connectToHost(hostName,port);
    qDebug() << "链接成功";

    //if链接服务器成功,Cli发送一个connect信号,由于该链接之链接一次所以写于构造函数中
}

void Cli::connect_slot()
{
    QMessageBox::information(this,"连线","链接成功");

    QString msg = userName + ":进入聊天室";

    socket->write(msg.toLocal8Bit());
}

void Cli::readyRead_slot()
{
    //读取客户端的数据
    QByteArray msg = socket->readAll();
    //数据展示在UI界面上
    ui->Listw->addItem(QString::fromLocal8Bit(msg));
}

void Cli::on_sendSB3_clicked()
{
    //获取ui界面输入的内容
    QString m = ui->msged->text();

    //整合信息
    QString msg = userName + ": " + m;

    socket->write(msg.toLocal8Bit());
}

void Cli::on_disconnectSB2_2_clicked()//断开服务器
{
    //准备要发送的信息
    QString msg = userName + ": 离开聊天室";
    socket->write(msg.toLocal8Bit());

    socket->disconnectFromHost();

    //断开后,客户端自动发送一个disconnect信号=>将该connect信号与槽函数链接
}

void Cli::disconnected_slot()
{
    QMessageBox::information(this,"断开链接","断开成功");
}

void Cli::on_SB4_clicked()
{
    ui->Listw->clear();
}
.h
=================================================================
#ifndef CLI_H
#define CLI_H

#include <QWidget>
#include <QTcpServer>//服务器
#include <QTcpSocket>//客户段
#include <QList>//链表   存放客户端的容器
#include <QDebug>
#include <QMessageBox>//消息

QT_BEGIN_NAMESPACE
namespace Ui { class Cli; }
QT_END_NAMESPACE

class Cli : public QWidget
{
    Q_OBJECT

public:
    Cli(QWidget *parent = nullptr);
    ~Cli();

private slots:
    void on_connectSB1_2_clicked();
    void connect_slot();//处理connect信号的槽函数
    void readyRead_slot();//处理readyRead信号的槽函数

    void on_sendSB3_clicked();//发送数据

    void on_disconnectSB2_2_clicked();//断开服务器

    void disconnected_slot();//disconnected信号 断开服务器提示
    void on_SB4_clicked();

private:
    Ui::Cli *ui;

    //QTcpServer *server;
    QTcpSocket *socket;
    QString userName;

};
#endif // CLI_H
.pro
=================================================================
QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    cli.cpp

HEADERS += \
    cli.h

FORMS += \
    cli.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
.main
=================================================================
#include "cli.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Cli w;
    w.show();
    return a.exec();
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

20230904 QT客户端服务器搭建聊天室 的相关文章

随机推荐

  • 据说还有比Mybatis Plus好用的ORM框架?还是阿里出的!

    来源 juejin cn post 6886019929519177735 使用fluent mybatis可以不用写具体的xml文件 通过java api可以构造出比较复杂的业务sql语句 做到代码逻辑和sql逻辑的合一 不再需要在Dao
  • Linux系统管理实践(2):OpenSSH远程管理配置

    OpenSSH是SSH Secure SHell 协议的免费开源实现 它用安全 加密的网络连接工具代替了telnet ftp rlogin rsh和rcp工具 OpenSSH支持SSH协议的版本1 3 1 5和2 SSH协议族可以用来进行远
  • 6.5V~65V用于电动自行车/汽车照明的同步降压恒流芯片LN4524

    6 5V 65V用于电动自行车 汽车照明的同步降压恒流芯片LN4524 LN4524 是一款外围电路简单 连续工作模式非隔离式恒流 LED 驱动控制芯片 LN4524 采用了 PWM 工作模式 在应用中可以采用较小值的电感 芯片外置 PMO
  • vivado创建IP时出现IP_Flow 19-3153] Bus Interface ‘user_clk‘: ASSOCIATED_BUSIF bus parameter is missing解决

    我新建IP时 里面添加了一个自己的输入时钟 系统默认给添加到了时钟和复位信号里面了 如下图箭头指示 然后提示 解决办法 其实就是按照其提示给这个信号添加bus parameter ASSOCIATED BUSIF 右键单击上图红色箭头指示的
  • Scrapy中使用Selenium

    Scrapy中使用Selenium可以通过以下步骤实现 1 安装Selenium库 可以通过pip安装selenium库 pip install selenium 2 下载浏览器驱动 Selenium需要浏览器驱动来控制浏览器 可以下载对应
  • Win10 安装系统跳过创建用户,直接启用 Administrator

    oobe 到创建用户那里 第一种方法 按 shift F10 打开 cmd 输入 lusrmgr msc 将 administrator 启用 关闭 lusrmgr msc 回到 cmd 输入 taskmgr exe 打开任务管理器 结束进
  • (三) 计算机图形学 之 Shader 定义 (顶点 着色器)

    shader 决定材质 跟灯光的作用 shader 属性定义的通用格式 Properties Property Property 相当于一个类的公共变量 Properties 定义一个Int name display name Int 1
  • 身份证省市区SQL代码

    转载自 https blog csdn net xiaofanku article details 18085865 身份证号码的意义 前1 2位数字表示 所在省份的代码 第3 4位数字表示 所在城市的代码 第5 6位数字表示 所在区县的代
  • JWT讲解

    目录 什么是JWT 为什么会出现JWT cookie session模式 JWT模式 JWT认证过程 JWT数据格式 优点 缺点 什么是JWT 为什么会出现JWT cookie session模式 传统cookie session模式是通过
  • stm32中断详解

    中断介绍 1 在单片机系统中 如果遇到需要紧急处理的突发事件时 CPU需要迅速的作出反应 暂停正在运行的程序来处理突发事件 这时就需要中断 2 中断是指单片机正在执行程序的时 发生突发事件从而打断当前程序 转而去处理这一事件 当处理完成后再
  • this.el_.vjs_getProperty is not a function

    前言 在使用video js播放rtmp视频中切换页面 如果是弹框引入 关闭弹框时 必然会发现控制台报错这个 这是谈谈我这边遇到的这个问题 以及怎么解决的 问题 在说这个问题怎么解决之前 先说一下我这边的应用场景 以及遇到的问题 我这边使用
  • 高端大气的艺术海报的ps教程

    Step 1海报尺寸宽和高为768 1152像素 分辨率150像素 英寸 背景白色 Step 2 确定了之后复制背景图层 双击图层进入图层样式 选择渐变叠加 颜色渐变绿色到蓝色 线性渐变 Step 3 用椭圆工具绘制正圆填充颜色白色 大小为
  • 竞赛——【蓝桥杯】2022年11月第十四届蓝桥杯模拟赛第一期Java

    1 二进制位数 问题描述 十进制整数 2 在十进制中是 1 位数 在二进制中对应 10 是 2 位数 十进制整数 22 在十进制中是 2 位数 在二进制中对应 10110 是 5 位数 请问十进制整数 2022 在二进制中是几位数 答案提交
  • 外网访问内网kafka无法链接

    根据业务需要 需要在外网访问内网的kafka 外网设备给内网推送数据 以为只需要通过NGINX代理kafka的端口就可以了 但是实际上端口代理后 端口可以链接 但是无法推送数据 猜测大概原因是因为 kafka是将链接信息注册到zookeep
  • 香港Web3欲戴王冠,银行如何承受合规之重?

    前言 6月19日 据明报报道 香港金融管理局 HKMA 总裁余伟文针对虚拟资产交易平台在香港银行开户难问题表示 一向有与香港银行有交流 交流时是否有压力则大家感觉不一 上周四 HKMA向汇丰银行 渣打银行和中国银行施压 要求其接受加密交易所
  • 后钢板弹簧吊耳—铣叉口两内侧面夹具设计

    摘 要 本次设计是对后钢板弹簧吊耳零件的加工工艺规程及一些工序的专用夹具设计 后钢板弹簧吊零件的主要加工表面是平面及孔 由加工工艺原则可知 保证平面的加工精度要比保证孔的加工精度容易 所以本设计遵循先面后孔的原则 并将孔与平面的加工明确划分
  • mysql中LEFT JOIN分页时的优化方法

    引言 查询的时候使用LEFT JOIN 配合分页要怎么优化 正文 常见的 分页SQL SELECT FROM table1 t1 LEFT JOIN table2 t2 ON t2 id t1 id LEFT JOIN table3 t3
  • 双点双向重发布小实验

    要求 1 如图搭建网络拓扑 所有路由器各自创建一个环回接口 合理规划IP地址 2 R1 R2 R2 R4 R6之间运行OSPF协议 R4 R5 R6之间运行RIP协议 3 R1环回重发布方式引入OSPF网络 4 R4 R6双点双向重发布 5
  • 华为OJ(记负均正)

    描述 从输入任意个整型数 统计其中的负数个数并求所有非负数的平均值 输入 输入任意个整数 输出 输出负数个数以及所有非负数的平均值 注意 当输入的数字的个数未知时 ivec的用法 以 0结束输入 样例测试 输入 13 4 7 输出 3 0
  • 20230904 QT客户端服务器搭建聊天室

    Ser cpp include app h include ui app h APP APP QWidget parent QWidget parent ui new Ui APP ui gt setupUi this this gt re