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

news2024/10/7 8:30:59

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();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/971241.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

爬虫源码---爬取自己想要看的小说

前言&#xff1a; 小说作为在自己空闲时间下的消遣工具&#xff0c;对我们打发空闲时间很有帮助&#xff0c;而我们在网站上面浏览小说时会被广告和其他一些东西影响我们的观看体验&#xff0c;而这时我们就可以利用爬虫将我们想要观看的小说下载下来&#xff0c;这样就不会担…

突破瓶颈:如何应对高级职位的面试

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

K8S自动化运维容器Docker集群

K8S&#xff1a;K8S自动化运维容器化(Docker)集群 一.k8s概述 1.k8s是什么 &#xff08;1&#xff09;K8S全程为Kubernetes&#xff0c;由于K到S直接有8个字母简称为K8S。 &#xff08;2&#xff09;版本&#xff1a;目前一般是1.18~1.2.0&#xff0c;后续可能会到1.24-1.2…

Qt 开发 CMake工程

Qt 入门实战教程&#xff08;目录&#xff09; 为何要写这篇文章 目前CMake作为C/C工程的构建方式在开源社区已经成为主流。 企业中也是能用CMake的尽量在用。 Windows 环境下的VC工程都是能不用就不用。 但是&#xff0c;这个过程是非常缓慢的&#xff0c;所以&#xff0…

Linux 学习笔记(2)—— 关于文件和目录

目录 1、切换目录 2、查看系统信息 3、文本的创建和编辑 3-1&#xff09;创建文件 3-2&#xff09;查看文件 3-3&#xff09;输出重定向和追加重定向 3-4&#xff09;使用 vi 编辑器编辑文件 4、文件和文件夹的处理 4-1&#xff09;对文件的处理 4-2&#xff09;查看…

avue实现用户本地保存自定义配置字段属性及注意事项(基于tj-vue2-tools)

avue实现用户本地保存自定义配置字段属性及注意事项&#xff08;基于tj-vue2-tools&#xff09; tj-vue2-tools项目地址&#xff1a;https://www.npmjs.com/package/tj-vue2-tools 文档请看项目官方 依赖js-base64 安装依赖 npm install js-base64安装 npm install tj-vue2-t…

Linux代码初试__进度条

前言 在我们的日常生活中&#xff0c;进度条是十分常见的&#xff0c;比如在软件下载中&#xff0c;应用加载中等等~~~那么进度条有什么特点&#xff1f;他又如何实现。 下面我们将结合下面的图展开讲解 一、前置理论知识 1.1回车和换行的区别 在我们的日常生活中&#x…

qt连接tcp通信和连接数据库

通过数据库实现学生管理系统 widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//判断数据库对象是否包含了自己使用的数据库 Studemt.dbif(!db.co…

国产集成开发环境工具 CEC-IDE

本周&#xff0c;国内首款适配国产操作系统、自主可控的集成开发环境工具 CEC-IDE 终于开放下载了。公开报道显示&#xff0c;这款集成开发环境工具由数字广东公司联合麒麟软件打造&#xff0c;于今年 6 月份首次亮相。本周&#xff0c;软件上线仅几天内就在知乎和 GitHub 上引…

《存储IO路径》专题:块设备层多队列blk-mq架构

我们想象一下&#xff0c;你是一个餐厅的厨师&#xff0c;你要准备很多不同的菜肴&#xff0c;而每种菜肴需要不同的食材和烹饪时间。如果每道菜都按照需要的顺序来准备&#xff0c;那么你的工作效率一定会非常低。为了提高效率&#xff0c;你会怎么做呢&#xff1f; 在linux架…

分布式 - 服务器Nginx:基础系列之Nginx静态资源优化配置指令sendfile | tcp_nopush | tcp_nodelay

文章目录 1. sendfile 指令2. tcp_nopush 指令3. tcp_nodelay 指令 1. sendfile 指令 请求静态资源的过程&#xff1a;客户端通过网络接口向服务端发送请求&#xff0c;操作系统将这些客户端的请求传递给服务器端应用程序&#xff0c;服务器端应用程序会处理这些请求&#xff…

qt day5 数据库,tcp

数据库 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QSqlDatabase>//数据库管理类 #include <QSqlRecord>//记录类 #include <QSqlQuery>//执行sql语句对应的类 #include <QMessageBox> #include<QDebug> …

Linux命令200例:man用于显示和阅读关于Linux内置命令的使用说明

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0…

玻璃工艺品可以走墨西哥专线吗?

玻璃工艺品作为一种精美独特的艺术品&#xff0c;经常被人们用来装饰家居或作为礼品赠送。然而&#xff0c;对于想要将这些玻璃工艺品运往墨西哥的商家或个人来说&#xff0c;如何选择最便捷的运输方式成为一个重要的问题。那么&#xff0c;玻璃工艺品可以走墨西哥专线吗? 墨西…

VSCode配置Python以及扩展

无论您是经验丰富的开发人员还是刚刚开始编码冒险&#xff0c;正确设置 VS Code 都可能是将您的技能提升到新水平的秘诀。因此&#xff0c;让我们深入探索在 Visual Studio Code 的虚拟墙内打造崇高编码天堂的艺术&#xff01; 为什么选择 VS 代码&#xff1f; VS Code 已成为 …

探索iVX:颠覆传统低代码平台的新潮流

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

判断对象是否发生变化,常用于监听页面表单是否修改并给出保存提示

本文主要封装方法&#xff0c;实现用户离开表单编辑页面时弹出提示框&#xff0c;若表单数据发生变化&#xff0c;则提示用户是否保存当前页面的信息&#xff0c;如图&#xff1a; 封装方法&#xff1a; /*** 比较俩个对象之间的差异&#xff0c;项目中多处用到监听表单数据是…

一文入门Web网站安全测试

文章目录 Web网页安全风险评估1. 数据泄漏2. 恶意软件传播3. 身份伪装和欺诈 测试Web网页的安全性常见方法和工具漏洞扫描器手动漏洞测试漏洞利用工具Web应用程序防火墙&#xff08;WAF&#xff09;测试渗透测试代码审查社会工程学测试 推荐阅读 Web网页安全风险评估 越来越多…

L1-058 6翻了(Python实现) 测试点全过

前言&#xff1a; {\color{Blue}前言&#xff1a;} 前言&#xff1a; 本系列题使用的是&#xff0c;“PTA中的团体程序设计天梯赛——练习集”的题库&#xff0c;难度有L1、L2、L3三个等级&#xff0c;分别对应团体程序设计天梯赛的三个难度。更新取决于题目的难度&#xff0c;…

ROS通信机制之动作(Action)服务的实践

1、动作概述 讲完了 服务 之后&#xff0c;接下来就是通信的第三种机制&#xff0c;动作。在上节我们知道服务的应用场景是需要在有限时间内完成&#xff0c;而对于一些比较复杂的任务&#xff0c;需要耗时比较长&#xff0c;甚至是不确定时间的时候&#xff0c;就需要用到动作…