当前位置: 首页 > news >正文

QT实现TCP/UDP通信

服务器端:

客户端:

服务器:

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
#include <QList>
#include <QMessageBox>
#include <QDebug>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots://自定义处理信号与槽函数void on_startButton_clicked();void newConnection_slot();void readyRead_slot();private:Ui::Widget *ui;QTcpServer *server;//定义服务器指针QList<QTcpSocket*> socketList;//定义存放客户端信息的容器};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//实例化一个服务器对象server = new QTcpServer(this);//在堆区申请一个服务器}Widget::~Widget()
{delete ui;
}//启动服务器按钮对应的槽函数
void Widget::on_startButton_clicked()
{if(ui->startButton->text()== "启动服务器"){//执行启动服务器动作//获取ui界面的端口号  ???quint16 port = ui->portEdit->text().toUInt();//启动监听//函数原型 bool listen(const QHostAddress &address = QHostAddress::any,quint16 port = 0);//1->要监听的ip地址 写any 表示监听该主机上所有的网络接口//2->要监听的端口号 不指定 系统默认随机绑定一个端口号if(!server->listen(QHostAddress::Any,port)){QMessageBox::critical(this,"错误","服务器启动失败");return;}//程序启动至此表示服务器启动成功QMessageBox::information(this,"成功","服务器启动成功");//将行编辑器设置为不可用ui->portEdit->setEnabled(false);//将按钮文本内容设置为关闭服务器ui->startButton->setText("关闭服务器");//此时 如果有客户端发来请求 那么该服务器会自动发射一个newConnection信号//将该信号连接到自定槽函数中处理后续操作connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);}else{//执行关闭服务器操作server->close();//将行编辑器设置成为可用状态ui->portEdit->setEnabled(true);//将按钮文本内容设置为启动服务器ui->startButton->setText("启动服务器");}
}void Widget::newConnection_slot()
{qDebug()<<"有新的客户端发来连接请求";//可以通过nextPendingConnection函数获取最新连接的客户端套接字的地址//函数原型 QTcpSocket *nextPendingConnection();//无参函数//返回值 最新的连接的套接字地址QTcpSocket *s = server->nextPendingConnection();//将套接字地址放入链表中socketList.push_back(s);//一个服务器对应多个客户端 已经建立连接//如果有客户端发来消息 自动发射readyRead信号connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
}
void Widget::readyRead_slot()
{//遍历链表中的所有客户端 如果客户端状态未连接 则直接移除出链表for (int i=0 ;i<socketList.size();i++){//判断当前套接字 socketList[i] 是否失效//函数原型 SocketState state() const;//返回值 返回当前调节子状态//返回结果为0 表示未连接if(socketList[i]->state()==0){socketList.removeAt(i);}}//遍历所有客户端 判断客户端中是否有数据刻度 如果有数据可读 则表示该客户端发来的消息for (int i =0;i<socketList.count();i++){//判断当前 客户端中是否有数据可读//函数原型 qint64 byteAvailable() const overrde//参数无//返回值为当前客户端套接字中的待读数据 如果没有数据 则返回0if(socketList[i]->bytesAvailable()  !=0){//读取当前套接字的内容QByteArray msg = socketList[i]->readAll();//将接受的消息展示到ui界面上ui->msgListWidget->addItem(QString::fromLocal8Bit(msg));//将收到的消息 全部发给其他客户端for (int j=0;j<socketList.length();j++){if (i!=j){socketList[j]->write(msg);}}}}
}

客户端

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include<QTcpSocket>         //客户端套接字类
#include<QMessageBox>        //消息对话框类QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_connectBtn_clicked();void connected_slot();           //自定义处理connected信号的槽函数void readyRead_slot();           //自定义处理readyRead信号的槽函数void disconnected_slot();        //自定义处理disconnected信号的槽函数void on_sendBtn_clicked();void on_disConnectBtn_clicked();private:Ui::Widget *ui;//定义通信用的变量QTcpSocket *client;         //定义套接字指针QString userName;           //用户名};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//实例化客户端对象client = new QTcpSocket(this);//当客户端与服务器建立联系后,如果客户端接受到服务器发来的消息//客户端自身就会自动发射一个 readyRead的信号,我们可以将该信号连接到自定义的槽函数中执行相关逻辑connect(client, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);//如果当前客户端成功连接的服务器,那么该客户端就会自动发射一个connected的信号//我们可以将该信号连接到自定义的槽函数中处理相关逻辑connect(client, &QTcpSocket::connected, this, &Widget::connected_slot);//当客户端断开了与服务器的连接后,该客户端就会自动发射一个disconnected的信号//我们可以将该信号连接到自定义的槽函数中处理相关逻辑connect(client, &QTcpSocket::disconnected, this, &Widget::disconnected_slot);
}Widget::~Widget()
{delete ui;
}//连接服务器按钮对应的槽函数
void Widget::on_connectBtn_clicked()
{//获取ui界面上的数据QString ip = ui->ipEdit->text();     //ip地址quint16 port = ui->portEdit->text().toUInt();    //端口号userName = ui->nameEdit->text();              //用户名//调用套接字成员函数,连接服务器//函数原型:void connectToHost(const QHostAddress &address, quint16 port, OpenMode mode = ReadWrite);//参数1:要被连接的服务器ip地址//参数2:服务器的端口号//参数3:默认为可读可写//返回值:无client->connectToHost(ip, port);
}//处理connected信号的槽函数的定义
void Widget::connected_slot()
{QMessageBox::information(this,"成功","连接成功");//将相关组件禁用ui->ipEdit->setEnabled(false);ui->nameEdit->setEnabled(false);ui->portEdit->setEnabled(false);ui->connectBtn->setEnabled(false);//向服务器发送一条消息QString msg = userName + ": 进入聊天室";client->write( msg.toLocal8Bit() );
}//自定义处理readyRead信号的槽函数
void Widget::readyRead_slot()
{//从套接字中读取数据QByteArray msg = client->readAll();//将读取下来的数据展示到ui界面上ui->msgListWidget->addItem( QString::fromLocal8Bit(msg) );
}//消息发送按钮对应的槽函数
void Widget::on_sendBtn_clicked()
{//组织要发送的消息QString msg = userName + ": " + ui->msgEdit->text();//将消息发送给服务器client->write(msg.toLocal8Bit());//将消息展示到自己界面上//准备一个QListWidgetItem类的对象QListWidgetItem *item = new QListWidgetItem(msg);item->setTextAlignment(Qt::AlignRight);        //将文本右对齐ui->msgListWidget->addItem(item);//清空消息发送框的内容ui->msgEdit->clear();
}//断开连接按钮对应的槽函数
void Widget::on_disConnectBtn_clicked()
{//执行断开连接的操作//准备发送消息给服务器QString msg = userName + ": 离开聊天室";client->write(msg.toLocal8Bit());//断开连接client->disconnectFromHost();
}//自定义处理disconnected信号的槽函数的定义
void Widget::disconnected_slot()
{QMessageBox::information(this, "提示", "成功断开与服务器的连接");//将相关组件启用ui->ipEdit->setEnabled(true);ui->nameEdit->setEnabled(true);ui->portEdit->setEnabled(true);ui->connectBtn->setEnabled(true);
}

相关文章:

QT实现TCP/UDP通信

服务器端&#xff1a; 客户端&#xff1a; 服务器&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QTcpSocket> #include <QList> #include <QMessageBox> #include <QDebug&…...

流程自动化变革:看低代码开发如何赋能企业创新转型

在数字化转型的浪潮中&#xff0c;企业面临着前所未有的挑战和机遇。为了保持竞争力&#xff0c;企业必须快速适应市场变化&#xff0c;创新业务模式&#xff0c;并提高运营效率。流程自动化成为企业转型的关键&#xff0c;而低代码开发平台如JNPF&#xff0c;正成为推动这一变…...

可提示 3D 分割研究里程碑!SAM2Point:SAM2加持泛化任意3D场景、任意提示!

郑重声明&#xff1a;本解读已获得论文作者的原创解读授权 文章链接&#xff1a;https://arxiv.org/pdf/2408.16768 在线demo: https://huggingface.co/spaces/ZiyuG/SAM2Point code链接&#xff1a;https://github.com/ZiyuGuo99/SAM2Point 亮点直击 无投影 3D 分割&#xff1…...

Rabbitmq中得RPC调用代码详解

文章目录 1.RPC客户端2.RabbitMQ连接信息实体类3.XML工具类 本文档只是为了留档方便以后工作运维&#xff0c;或者给同事分享文档内容比较简陋命令也不是特别全&#xff0c;不适合小白观看&#xff0c;如有不懂可以私信&#xff0c;上班期间都是在得 直接上代码了 1.RPC客户端 …...

ISAC: Toward Dual-Functional Wireless Networks for 6G and Beyond【论文阅读笔记】

此系列是本人阅读论文过程中的简单笔记&#xff0c;比较随意且具有严重的偏向性&#xff08;偏向自己研究方向和感兴趣的&#xff09;&#xff0c;随缘分享&#xff0c;共同进步~ Integrated Sensing and Communications: Toward Dual-Functional Wireless Networks for 6G and…...

split 分割字符串方法解析,substring 截取字符串方法解析;二者的作用和区别?使用时需要注意什么?附代码和运行图

目录 一. 摘要 二. split 方法 2.1 String[] split(String regix) 2.2 String[] split(String regix&#xff0c;int limit) 2.3.1 当 int < 0时&#xff0c;会按照最大数量切割字符串 2.3.2 当 int 0时&#xff0c;此时就和第一个方法一样了&#xff0c;等于没有传入…...

HTTP 协议的基本格式

HTTP协议("超文本传输协议")&#xff0c;是一个被广泛使用应用层协议&#xff0c;自1991年正式发布HTTP协议以来&#xff0c;HTTP协议就一直在更新&#xff0c;目前已经更新到3.0版本&#xff0c;但是目前主流的依旧是1.1版本&#xff0c;但依旧是一个最主流使用的应…...

STM32-HAL库开发快速入门

注:本文主要记录一下STM32CubeMX软件的使用流程,记录内容以STM32外设&#xff08;中断、I2C、USART、SPI等配置&#xff09;在STM32CubeMX中的设置为主&#xff0c;对驱动代码编写不做记录&#xff0c;所以阅读本文最好有标准库开发经验。除第2节外&#xff0c;使用的都是韦东山…...

vue3-print打印eletable某一行的数据

主页面的表格 <template><el-table :data"list"><el-table-column label"操作" align"center"><template #default"scope"><el-buttonlinktype"primary"click"handleType(scope.row)"…...

【Vue】pnpm创建Vue3+Vite项目

初始化项目 &#xff08;1&#xff09;cmd切换到指定工作目录&#xff0c;运行pnpm create vue命令&#xff0c;输入项目名称后按需安装组件 &#xff08;2&#xff09;使用vs code打开所创建的项目目录&#xff0c;Ctrl~快捷键打开终端&#xff0c;输入pnpm install下载项目…...

springboot配置多数据源

springboot配置多数据源 学习新技术&#xff0c;争做新青年&#xff0c;欢迎围观&#xff0c;河南老乡在上海请&#xff0c;加&#xff0c;微&#xff0c;andyfau2022&#xff0c; ----获取数据源&#xff1a;null&#xff0c;数据源为null时默认使用主数据源的。 1-yml文件…...

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题&#xff1a;墙体两侧特征混淆误匹配&#xff0c;导致建图和定位偏差&#xff0c;表现为过门跳变、外月台走歪等 解决思路&#xff1a;预期的根治方案IGICP需要较长时间完成上线&#xff0c;先使用切分地图的工程化方案&#xff0c;即墙体两侧切…...

ChatGPT+Simple Mind Map生成思维导图:快速提升学习效率

一、告别杂乱笔记&#xff0c;一键生成清晰思维导图&#xff01; 最近开始学习网络安全&#xff0c;一头扎进了各种协议、漏洞、防御机制的海洋中。信息量巨大&#xff0c;知识点零散&#xff0c;让我很快便陷入了“知识焦虑”——笔记越记越多&#xff0c;却越来越混乱&#…...

Day9 | Java框架 | SpringBoot

Day9 | Java框架 | SpringBoot SpringBoot简介入门程序概述起步依赖 基础配置配置文件格式&#xff1a;3种yaml语法规则yaml数据读取三种格式 多环境启动配置文件参数命令行参数多环境开发控制&#xff1a;Maven & SpringBoot 多环境兼容 配置文件分类&#xff1a;4种 整合…...

Wordpress右下角表单弹出插件

Ultimate Sticky Popup & Widgets Charcoal Making Machine | Equipment for Sale - Kingtiger...

影刀RPA实战:自动化批量生成条形码完整指南

今天我们聊聊使用影刀来实现批量生成条形码&#xff0c;条形码在零售行业运用非常广泛&#xff0c;主要作用表现在产品识别&#xff0c;库存管理&#xff0c;销售管理&#xff0c;防伪保护等&#xff0c;这些作用使其成为现代商业和工业环境中不可或缺的工具&#xff0c;它极大…...

Python Flask简介

简介 Flask 有两个主要依赖&#xff1a;路由、调试和 Web 服务器网关接口&#xff08;Web Server Gateway Interface&#xff0c;WSGI&#xff09; 子系统由&#xff1a;Werkzeug 提供模板系统由&#xff1a;Jinja2提供Werkzeug 和 Jinjia2 都是由 Flask 的核心开发者开发而成…...

视频监控平台是如何运作的?EasyCVR视频汇聚平台的高效策略与实践

随着科技的飞速发展&#xff0c;视频监控平台在社会安全、企业管理、智慧城市构建等领域发挥着越来越重要的作用。一个高效的视频监控平台&#xff0c;不仅依赖于先进的硬件设备&#xff0c;更离不开强大的视频处理技术作为支撑。这些平台集成了多种先进的视频技术&#xff0c;…...

欧拉下搭建第三方软件仓库—docker

1.创建新的文件内容 切换目录到etc底下的yum.repos.d目录&#xff0c;创建docker-ce.repo文件 [rootlocalhost yum.repos.d]# cd /etc/yum.repos.d/ [rootlocalhost yum.repos.d]# vim docker-ce.repo 编辑文件,使用阿里源镜像源&#xff0c;镜像源在编辑中需要单独复制 h…...

pcs升压变流一体机

在当今全球积极推进能源转型的大背景下&#xff0c;新能源技术的发展日新月异。其中&#xff0c;PCS 升压变流一体机作为一种关键的能源转换设备&#xff0c;正发挥着越来越重要的作用。它一般可分为10KV与35KV等级的。 PCS 升压变流一体机&#xff0c;全称为 Power Conversion…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...