20230904 QT客户端服务器搭建聊天室
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_NAMESPACEclass APP : public QWidget
{Q_OBJECTpublic: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_HT1.pro
=================================================================
QT += core gui networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += 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.0SOURCES += \main.cpp \app.cppHEADERS += \app.hFORMS += \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=>readyReadconnect(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 USERQString s1 = "八嘎";userName = s1;//QString hostName = ui->IPed->text();//get IPQString s2 = "192.168.124.72";QString hostName = s2;quint16 port = ui->PORTed->text().toUInt();//get PORTqDebug() << "获取信息-----";//链接主机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_NAMESPACEclass Cli : public QWidget
{Q_OBJECTpublic: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 networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += 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.0SOURCES += \main.cpp \cli.cppHEADERS += \cli.hFORMS += \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();
}

相关文章:
20230904 QT客户端服务器搭建聊天室
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->se…...
吴恩达gradio课程:基于开源LLM(large language model)的聊天应用chatbot
文章目录 内容简介构建应用程序使用gradio在线体验接下来结合llm模型使用gradio构建一个完整的应用程序内容简介 Falcon 40B是当前最好的开源语言模型之一。使用text-generation库调用Falcon 40B的问答API接口。首先仅仅在代码中与模型聊天,后续通过Gradio构建聊天界面。Gradio…...
【c++】weak_ptrshared_ptr
目录 weak_ptr&shared_ptr 为什么不直接使用this指针 weak_ptr&shared_ptr weak_ptr<RtspSession> weakSelf dynamic_pointer_cast<RtspSession>(shared_from_this()); 这段代码涉及到 C 中的 weak_ptr 和 shared_ptr 的使用,以及类型转换…...
Init函数和main函数
1.Init函数和main函数 1.1. init函数 go语言中init函数用于包(package)的初始化,该函数是go语言的一个重要特性。 有下面的特征: 1 init函数是用于程序执行前做包的初始化的函数,比如初始化包里的变量等2 每个包可以拥有多个init函数3 包的…...
汇川PLC学习Day1:跑马灯程序编写
汇川PLC学习Day1:跑马灯程序编写 一、 软件安装 进入官网下载软件 二、 使用帮助 三、 新建工程与功能代码实现 CtrlN 寻找内带输出模块的CPU并设置好工程名字与保存路径,语言选择想熟悉的类型 工程建立后,PLC_PRG即为用户编写程序文件…...
【已解决】Unknown initial character set index ‘45‘ received from server
出现这个数据库连接异常,可能是数据库太新,所以更新一下JDBC连接驱动,原来的是5.0.4 ,现在换成5.1.47.连接成功。 参考其他博主的文章:Java——连接数据库MySQL 5.7和8.0的区别_这段语句mysql5.7和8.0有什么区别url: …...
Java从入门到精通-数组(二)
4.数组的基本操作 数组的基本操作包括遍历数组、填充替换数组元素、对数组进行排序、复制数组以及查询数组中的元素。 • 4.1 遍历数组 遍历数组是访问数组中所有元素的过程,通常使用循环完成。 使用 for 循环遍历数组: int[] numbers {1, 2, 3, 4…...
深入剖析HTTP和HTTPS代理在爬虫中的应用价值
在当今信息时代,数据是无处不在且极其宝贵的资源。对于从互联网上获取大量结构化或非结构化数据的需求而言,网络爬虫成为一种强有力的工具。然而,在实际操作过程中,我们常常会面临许多挑战和限制。 其中一个主要问题就是目标网…...
SQL语句分类及编写规范
目录 1.SQL分类 数据定义语言 DDL 数据操纵语言 DML 数据查询语言 DQL 数据控制语言 DCL 事务控制语言 TCL 2.SQL语句的编写规范 SQL语句不区分大小写 SQL语句关键词建议大写 SQL语句每句话用分号结尾 MySQL从小白到总裁完整教程目录:https://blog.csdn.net/wei…...
02-zookeeper分布式锁案例
1 Zookeeper分布式案例 1.1 Zookeeper分布式锁原理 核心思想:当客户端要获取锁,则创建节点,使用完锁,则删除该节点。 当我们假设根节点/ 下有/locks节点时 1)客户端获取锁时,在locks节点下创建临时顺序…...
【Spring传播机制底层原理】
一、Spring的事务传播机制 Spring的事务传播机制是Spring框架中最核心的机制之一,它能够灵活地控制多个事务方法的执行顺序、提交或回滚等行为。在Spring中,事务是通过TxManager来管理的,TxManager是一个接口,提供了开启、提交、…...
python通过tkinter制作词云图工具
一、基本功能 1.采取上传文本文档(仅支持.txt格式)的方式统计词频 2.背景图形样式可选择已经设定好的,也可选择本地上传的(支持.png .jpg .jpeg格式) 3.本地上传的图片需要进行抠图处理,并将抠图结果保存…...
Java-钉钉订阅事件
文章目录 背景什么是钉钉订阅事件钉钉订阅事件的应用场景 整体思路查看钉钉文档 什么是钉钉回调钉钉回调具体实操创建自己的应用钉钉回调开发过程中遇到的问题 总结 背景 最近需要做一个业务:钉钉组织架构下添加人员之后,要对该人员的数据信息做一个处理…...
【DataV/echarts】vue中使用,修改地图和鼠标点击部分的背景色
引入:使用 DataV 引入地图的教程是参考别人的,主要介绍修改地图相关的样式; 引入地图 是参考别人的,这里自己再整理一遍,注意需要安装 5 版本以上的 echarts; DataV 网址:https://datav.aliyun.…...
系统设计类题目汇总四
25 十个异步入库任务,如何保证他们原子入库? 了解了你的问题背景,确保10个异步入库任务原子性执行(即要么全部成功,要么全部失败)有以下几种方法: 数据库事务: 如果所有的入库操作都是在同一个…...
【C++心愿便利店】No.5---构造函数和析构函数
文章目录 前言一、类的6个默认成员函数二、构造函数三、析构函数 前言 👧个人主页:小沈YO. 😚小编介绍:欢迎来到我的乱七八糟小星球🌝 📋专栏:C 心愿便利店 🔑本章内容:类…...
微软研究院团队获得首届AI药物研发算法大赛总冠军
编者按:AI 药物研发是人工智能未来应用的重要方向之一。自新冠病毒(SARS-CoV-2)首次爆发以来,新冠病毒的小分子药物研发备受关注,于近期举行的首届 AI 药物研发算法大赛便聚焦于此。在比赛中,来自微软研究院…...
redis实战篇之导入黑马点评项目
1. 搭建黑马点评项目 链接:https://pan.baidu.com/s/1Q0AAlb4jM-5Fc0H_RYUX-A?pwd6666 提取码:6666 1.1 首先,导入SQL文件 其中的表有: tb_user:用户表 tb_user_info:用户详情表 tb_shop:商户…...
【C++】详解红黑树并模拟实现
前言: 上篇文章我们一起学习了AVL树比模拟实现,我们发现AVL树成功地把时间复杂度降低到了O(logN)。但是同时我们不难发现一个问题,在构建AVL树中我们也付出了不小的代价,频繁的旋转操作导致效率变低。为了解决这个问题,…...
Matlab图像处理-最大类间方差阈值选择法(Otsu)
基本思想 最大类间方差阈值选择法又称为Otsu 算法,该算法是在灰度直方图的基础上用最小二乘法原理推导出来的,具有统计意义上的最佳分割阈值。它的基本原理是以最佳阈值将图像的灰度直方图分割成两部分,使两部分之间的方差取得最大值&#x…...
OPC UA over HTTPS解析卡顿,Modbus TCP粘包丢帧,Java工业协议解析故障全图谱,一线工程师紧急避坑手册
第一章:Java工业协议解析故障全景概览 在现代工业物联网(IIoT)系统中,Java 应用常作为上位机、网关或边缘服务承担 Modbus TCP、OPC UA、S7Comm、DNP3 等协议的解析与桥接任务。然而,由于协议语义复杂、设备厂商实现差…...
单细胞测序入门(一):技术概览与数据获取实战
1. 单细胞测序技术全景解读 第一次接触单细胞测序时,我被这项技术的精妙设计深深震撼。想象一下,传统测序就像把水果榨成混合果汁检测成分,而单细胞测序则是把每个苹果、香蕉、葡萄分开榨汁分析——这就是单细胞分辨率带来的革命性视角。 核心…...
XposedRimetHelper:如何优雅解决远程办公的定位打卡难题?[特殊字符]
XposedRimetHelper:如何优雅解决远程办公的定位打卡难题?🚀 【免费下载链接】XposedRimetHelper Xposed 钉钉辅助模块,暂时实现模拟位置。 项目地址: https://gitcode.com/gh_mirrors/xp/XposedRimetHelper 面对企业日益严…...
Zabbix 6.0部署避坑指南:为什么你的Ubuntu安装总卡在数据库初始化这一步?
Zabbix 6.0部署避坑指南:为什么你的Ubuntu安装总卡在数据库初始化这一步? 如果你正在Ubuntu上部署Zabbix 6.0,却反复在数据库初始化这一步失败,这篇文章就是为你准备的。不同于常规的安装教程,我们将聚焦于那些看似简…...
vLLM-v0.17.1部署实战教程:3步启用OpenAI兼容API服务
vLLM-v0.17.1部署实战教程:3步启用OpenAI兼容API服务 1. vLLM框架简介 vLLM是一个专为大型语言模型(LLM)设计的高性能推理和服务库,以其出色的速度和易用性著称。这个项目最初由加州大学伯克利分校的天空计算实验室开发,现在已经发展成为一…...
从羊肠小道到智能高速:HTTP1到HTTP3的演进之路
引言 计算机网络就像一张遍布全球的道路系统,服务器是一座座城市、村庄,客户端是穿梭其中的车辆,而HTTP协议,就是规范车辆通行、货物传递的交通规则。从HTTP1到HTTP3的演进,本质上就是这条“网络道路”的升级史——从泥…...
PyTorch 3.0静训性能断崖预警:当AllReduce延迟>8.3ms或图编译耗时>117s时,你的训练任务已在 silently fail——附实时诊断CLI工具
第一章:PyTorch 3.0静态图分布式训练的静默失效危机全景PyTorch 3.0 引入的 TorchScript 静态图编译机制与 torch.distributed 的深度耦合,在多节点多卡场景下暴露出一类高危静默失效现象:训练进程持续运行、梯度同步无报错、loss 曲线看似收…...
内网渗透实战:利用SSH密钥实现Linux主机间横向移动
1. SSH密钥横向移动的核心原理 当你第一次接触内网渗透时,可能会被各种复杂的技术术语吓到。其实SSH密钥横向移动的原理非常简单:就像用钥匙开锁一样,只要拿到目标主机的SSH私钥,就能像合法用户一样登录系统。我在实际渗透测试中发…...
网络基础知识整理(精简通用版)20260331-001篇
文章目录 网络基础知识整理(精简通用版) 一、网络基本概念 二、网络拓扑结构 三、OSI 七层模型(核心参考) 四、TCP/IP 模型(实际互联网标准) 五、IP 地址基础 六、传输层协议(TCP vs UDP) TCP(传输控制协议) UDP(用户数据报协议) 七、常见网络协议与端口 八、网络设…...
YOLO12入门必看:从上传图片到JSON结果输出完整操作流程
YOLO12入门必看:从上传图片到JSON结果输出完整操作流程 1. 引言:为什么你需要了解YOLO12? 如果你正在寻找一个既快又准的目标检测工具,那么YOLO12的出现,可能就是你一直在等的那个答案。 想象一下这样的场景&#x…...
