一、实验效果演示

实现 Qt 的 TCP 客户端,实现和服务器通信

二、代码框架

三、代码

tcpclient客户端代码

tcpclient.cpp

#include "tcpclient.h"
#include "ui_tcpclient.h"
#include <QDebug>
#include <QMessageBox>
#include <QRegExpValidator>// 构造函数:初始化TCP客户端界面和成员变量
tcpclient::tcpclient(QWidget *parent): QWidget(parent)                  // 调用父类QWidget的构造函数, ui(new Ui::tcpclient)            // 初始化UI对象, mSocket(nullptr)                 // 初始化TCP套接字指针为nullptr
{ui->setupUi(this);                 // 初始化UI界面setWindowTitle("TCP Client");      // 设置窗口标题为"TCP Client"// 初始状态下禁用发送功能(未连接服务器时不能发送数据)ui->lineEdit_send->setEnabled(false);  // 禁用发送内容输入框ui->pushButton_send->setEnabled(false); // 禁用发送按钮// 设置IP地址验证器,确保输入的IP地址格式正确// 创建正则表达式验证器,用于验证IPv4地址格式QRegExpValidator *ipValidator = new QRegExpValidator(// 正则表达式:匹配xxx.xxx.xxx.xxx格式的IPv4地址,每个xxx为0-255QRegExp("\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"),this  // 父对象为当前窗口,确保内存自动管理);ui->lineEdit_ip->setValidator(ipValidator);  // 为IP输入框设置验证器ui->lineEdit_ip->setText("192.168.53.128");  // 设置默认IP地址
}// 析构函数:释放资源
tcpclient::~tcpclient()
{// 如果套接字存在且处于连接状态,断开与服务器的连接if (mSocket && mSocket->state() == QAbstractSocket::ConnectedState) {mSocket->disconnectFromHost();}delete ui;  // 释放UI对象
}// "连接/断开"按钮点击事件处理函数
void tcpclient::on_pushButton_connect_clicked()
{// 如果套接字未初始化,创建QTcpSocket对象if (!mSocket) {mSocket = new QTcpSocket(this);  // 创建TCP套接字,父对象为当前窗口// 连接信号与槽函数,处理各种网络事件// 当连接成功建立时,触发onConnected函数connect(mSocket, &QTcpSocket::connected, this, &tcpclient::onConnected);// 当连接断开时,触发onDisconnected函数connect(mSocket, &QTcpSocket::disconnected, this, &tcpclient::onDisconnected);// 当有数据可读时,触发onReadyRead函数connect(mSocket, &QTcpSocket::readyRead, this, &tcpclient::onReadyRead);// 当发生错误时,触发onErrorOccurred函数(兼容旧版本Qt)connect(mSocket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error), this, &tcpclient::onErrorOccurred);    }// 检查当前连接状态if (mSocket->state() == QAbstractSocket::ConnectedState) {// 如果已连接,则断开连接mSocket->disconnectFromHost();} else {// 未连接状态,尝试连接到服务器QString ip = ui->lineEdit_ip->text();       // 获取输入的IP地址quint16 port = ui->spinBox_port->value();   // 获取输入的端口号// 检查IP地址是否为空if (ip.isEmpty()) {QMessageBox::warning(this, "警告", "请输入服务器IP地址");  // 弹出警告对话框return;  // 退出函数,不执行连接操作}// 连接到指定的IP地址和端口号mSocket->connectToHost(QHostAddress(ip), port);// 在消息显示区添加连接状态信息ui->textBrowser->insertPlainText("正在连接到 " + ip + ":" + QString::number(port) + "...\n");}
}// "发送"按钮点击事件处理函数
void tcpclient::on_pushButton_send_clicked()
{// 检查套接字是否存在且处于连接状态if (!mSocket || mSocket->state() != QAbstractSocket::ConnectedState) {return;  // 不满足条件则退出函数}// 获取要发送的数据QString str = ui->lineEdit_send->text();// 检查输入内容是否为空if (str.isEmpty()) {return;  // 内容为空则不发送}// 发送数据:将QString转换为UTF-8编码的字节数组mSocket->write(str.toUtf8());// 在界面上显示发送的内容,前缀"snd:"标识为发送的数据ui->textBrowser->insertPlainText("snd: " + str + "\n");// 清空发送输入框ui->lineEdit_send->clear();
}// 连接成功建立时的处理函数
void tcpclient::onConnected()
{// 在消息显示区添加连接成功信息ui->textBrowser->insertPlainText("已连接到服务器\n");// 将"连接"按钮文本改为"断开连接"ui->pushButton_connect->setText("断开连接");// 启用发送功能(连接成功后才能发送数据)ui->lineEdit_send->setEnabled(true);  // 启用发送内容输入框ui->pushButton_send->setEnabled(true); // 启用发送按钮// 禁用IP和端口编辑(连接建立后不允许修改连接参数)ui->lineEdit_ip->setEnabled(false);    // 禁用IP输入框ui->spinBox_port->setEnabled(false);   // 禁用端口选择框
}// 连接断开时的处理函数
void tcpclient::onDisconnected()
{// 在消息显示区添加断开连接信息ui->textBrowser->insertPlainText("已与服务器断开连接\n");// 将"断开连接"按钮文本改回"连接"ui->pushButton_connect->setText("连接");// 禁用发送功能(断开连接后不能发送数据)ui->lineEdit_send->setEnabled(false);  // 禁用发送内容输入框ui->pushButton_send->setEnabled(false); // 禁用发送按钮// 启用IP和端口编辑(断开连接后允许修改连接参数)ui->lineEdit_ip->setEnabled(true);     // 启用IP输入框ui->spinBox_port->setEnabled(true);    // 启用端口选择框
}// 有数据可读时的处理函数
void tcpclient::onReadyRead()
{// 检查套接字是否存在if (!mSocket) {return;  // 套接字不存在则退出}// 读取所有接收到的数据QByteArray data = mSocket->readAll();// 在界面上显示接收的内容,前缀"rcv:"标识为接收的数据ui->textBrowser->insertPlainText("rcv: " + QString(data) + "\n");
}// 网络错误发生时的处理函数
void tcpclient::onErrorOccurred(QAbstractSocket::SocketError error)
{Q_UNUSED(error);  // 标记error参数未使用,避免编译警告// 检查套接字是否存在if (mSocket) {// 在消息显示区添加错误信息ui->textBrowser->insertPlainText("错误: " + mSocket->errorString() + "\n");}
}

tcpclient.h

#ifndef TCPCLIENT_H  // 防止头文件被重复包含的宏定义
#define TCPCLIENT_H  // 定义头文件宏#include <QWidget>       // 包含QWidget类,tcpclient类继承自QWidget
#include <QTcpSocket>    // 包含QTcpSocket类,用于TCP通信
#include <QAbstractSocket> // 包含QAbstractSocket类,提供套接字的基本功能和枚举
#include <QRegExpValidator> // 包含QRegExpValidator类,用于正则表达式验证
#include <QMessageBox>   // 包含QMessageBox类,用于显示消息对话框
#include <QHostAddress>  // 包含QHostAddress类,用于处理IP地址QT_BEGIN_NAMESPACE  // Qt命名空间开始
namespace Ui { class tcpclient; }  // 声明Ui命名空间中的tcpclient类(由.ui文件生成)
QT_END_NAMESPACE    // Qt命名空间结束// 定义tcpclient类,继承自QWidget,用于实现TCP客户端功能
class tcpclient : public QWidget
{Q_OBJECT  // 启用Qt的元对象系统,支持信号和槽机制public:// 构造函数:创建tcpclient对象,parent为父窗口指针,默认为nullptrtcpclient(QWidget *parent = nullptr);// 析构函数:释放tcpclient对象占用的资源~tcpclient();private slots:  // 私有槽函数,用于处理各种事件// 处理"连接/断开"按钮的点击事件void on_pushButton_connect_clicked();// 处理"发送"按钮的点击事件void on_pushButton_send_clicked();// 处理连接成功建立的事件void onConnected();// 处理连接断开的事件void onDisconnected();// 处理有数据可读的事件void onReadyRead();// 处理网络错误发生的事件,参数为错误类型void onErrorOccurred(QAbstractSocket::SocketError error);private:  // 私有成员变量Ui::tcpclient *ui;  // 指向UI界面对象的指针,用于访问界面控件QTcpSocket *mSocket; // 指向QTcpSocket对象的指针,用于TCP通信
};#endif // TCPCLIENT_H  // 结束头文件宏定义

tcpclient.pro

QT       += core gui
QT += network
greaterThan(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 \tcpclient.cppHEADERS += \tcpclient.hFORMS += \tcpclient.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.cpp

#include "tcpclient.h"  // 包含tcpclient类的头文件,用于创建客户端窗口对象#include <QApplication>  // 包含QApplication类的头文件,Qt应用程序的核心类// 程序入口函数,argc是命令行参数数量,argv是命令行参数数组
int main(int argc, char *argv[])
{// 创建QApplication对象a,初始化Qt应用程序,处理命令行参数QApplication a(argc, argv);// 创建tcpclient类的实例w,这是客户端的主窗口对象tcpclient w;// 显示主窗口w,此时窗口才会在屏幕上可见w.show();// 进入Qt应用程序的事件循环,等待用户交互(如点击按钮、输入文本等)// 函数返回应用程序退出时的状态码return a.exec();
}

tcpclient.ui(8个组件)

  1. QT设计师界面UI 设计建议:
    客户端 UI 应包含以下元素:

    • IP 地址输入框(lineEdit_ip)
    • 端口号选择框(spinBox_port)
    • 连接 / 断开按钮(pushButton_connect)
    • 发送内容输入框(lineEdit_send)
    • 发送按钮(pushButton_send)
    • 消息显示区域(textBrowser)


6TcpServer服务器端

tcpsever.cpp

#include "tcpserver.h"
#include "ui_tcpserver.h"
#include <QDebug>TcpServer::TcpServer(QWidget *parent): QWidget(parent), ui(new Ui::TcpServer)
{ui->setupUi(this);
}TcpServer::~TcpServer()
{delete ui;
}void TcpServer::on_pushButton_start_clicked()
{//1.构建QTcpServer对象mServer = new QTcpServer(this);//连接有客户端连接上来的信号QObject::connect(mServer,&QTcpServer::newConnection,this,[&](){//获取客户端连接上来的套接字mSocket = mServer->nextPendingConnection();//获取客户端的地址QHostAddress addr = mSocket->peerAddress();qDebug()<<addr.toString()<<"连接上来!";//使能发送ui->lineEdit->setEnabled(true);ui->pushButton_send->setEnabled(true);//连接readyRead信号和槽QObject::connect(mSocket,&QTcpSocket::readyRead,this,[&](){//接收数据QByteArray arr = mSocket->readAll();//转换成字符串并显示QString str(arr);//显示ui->textBrowser->insertPlainText("rcv:"+str+"\n");});});//2.监听mServer->listen(QHostAddress::Any,ui->spinBox->value());//禁止修改ui->spinBox->setEnabled(false);ui->pushButton_start->setEnabled(false);
}//发送
void TcpServer::on_pushButton_send_clicked()
{//获取发送的数据QString str = ui->lineEdit->text();//转换成QByteArrayQByteArray arr;arr.append(str);//发送mSocket->write(arr);//显示要发送的内容ui->textBrowser->insertPlainText("snd:"+str+"\n");//清空ui->lineEdit->clear();
}

main.cpp

#include "tcpserver.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);TcpServer w;w.show();return a.exec();
}

tcpserver.h

#ifndef TCPSERVER_H
#define TCPSERVER_H#include <QWidget>
#include <QtNetwork>QT_BEGIN_NAMESPACE
namespace Ui { class TcpServer; }
QT_END_NAMESPACEclass TcpServer : public QWidget
{Q_OBJECTpublic:TcpServer(QWidget *parent = nullptr);~TcpServer();private slots:void on_pushButton_start_clicked();void on_pushButton_send_clicked();private:Ui::TcpServer *ui;//TCP服务器QTcpServer *mServer;QTcpSocket *mSocket;
};
#endif // TCPSERVER_H

6TcpServer.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 \tcpserver.cppHEADERS += \tcpserver.hFORMS += \tcpserver.ui# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

tcpserver.ui(6个组件)

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AR培训系统:油气行业的安全与效率革新

在油气行业&#xff0c;一场由增强现实&#xff08;AR www.teamhelper.cn &#xff09;技术引领的培训革命正在悄然发生。新员工们不再需要冒着生命危险在真实的钻井平台上学习操作&#xff0c;而是通过AR眼镜在虚拟环境中模拟钻井、起下钻甚至处理井喷等复杂操作。这种创新的培…

Linux 多线程:互斥与同步

Linux 多线程中的互斥与同步 —— pthread_mutex 与 semaphore在 Linux 多线程编程中&#xff0c;线程间共享全局变量或数据结构是常见场景。如果多个线程同时读写同一块内存&#xff0c;就可能产生 数据竞争 和 不一致。为了解决这些问题&#xff0c;Linux 提供了多种 线程同步…

技术演进中的开发沉思-81 Linux系列:进程地址空间

上一个篇幅和大家聊了进程地址空间、内存描述符这些 Linux 内存管理的 “基本功”&#xff0c;我的一些学生问&#xff1a;“这些概念听起来简单&#xff0c;可实际开发中怎么用得上&#xff1f;” 我想今天把这些 “理论骨架” 填上 “实践血肉”—— 毕竟我当年踩过的坑、摸过…

【联通分量】题解:P13823 「Diligent-OI R2 C」所谓伊人_连通分量_最短路_01bfs_图论_C++算法竞赛

洛谷博客&#xff1a;https://www.luogu.com.cn/article/5n200x7y Link - P13823 讨论区中有很多有用的 hack&#xff0c;没过的话可以去看看。 每个点都可以换到其所在弱连通分量的最大点权&#xff0c;这是毋庸置疑的。 为了方便陈述&#xff0c;下文中记当前弱连通分量中…

区块链+隐私计算护航“东数西算”数据安全报告

一、背景与政策支持1.1 "东数西算"工程概况战略定位&#xff1a;作为数字经济时代的核心"底座"&#xff0c;"东数西算"工程是国家级算力资源跨域调配战略工程&#xff0c;旨在构建全国一体化算力网络体系。启动时间与布局&#xff1a;2022年2月&…

STM32——PWR

一、PWR1.1PWR简介PWR&#xff08;Power Control&#xff09;电源控制PWR负责管理STM32内部的电源供电部分&#xff0c;可以实现可编程电压监测器和低功耗模式的功能可编程电压监测器&#xff08;PVD&#xff09;可以监控VDD电源电压&#xff0c;当VDD下降到PVD阀值以下或上升到…

Linux系统网络管理学习.2

目录 一、学习目标与适用场景 二、网络管理基础概念 1. NetworkManager服务 2. 核心管理工具 三、NetworkManager服务管理&#xff08;基础操作&#xff09; 1. 服务状态控制 四、网络参数配置&#xff08;IP/DNS/网关&#xff09; 1. 图形化配置&#xff08;仅了解&…

响应式编程之Flow框架

文章目录一、技术背景与产生原因1.1 响应式编程的兴起1.2 响应式流规范&#xff08;Reactive Streams&#xff09;1.3 解决的问题1.4 响应式编程二、Flow API核心组件2.1 核心概念2.2 接口关系图2.2 接口详解2.3 背压机制三、完整示例3.1 入门示例3.2 基础发布-订阅示例3.3 带背…

ABeam中国 | 中国汽车市场(5)——软件定义汽车(SDV)的智能化应用场景

前言本系列前四篇深入探讨了中国新能源汽车市场的崛起与电动化进程中的挑战。本文聚焦软件定义汽车&#xff08;SDV&#xff09;的三大核心应用场景 ——高级驾驶辅助系统&#xff08;ADAS&#xff09;、智能驾驶舱人机界面&#xff08;HMI&#xff09;及出行即服务&#xff08…

BugKu Web渗透之成绩查询

打开网页&#xff0c;页面如下&#xff1a;输入框中输入不同的数字可以查询不同的结果。输入1后点击submit按钮&#xff0c;下方出现成绩结果。从题目上看感觉是一个SQL注入的漏洞。思路有下&#xff1a;1.自己手动拼接一些常见的SQL注入。2.用bp抓包后用SQLMap去跑。首先&…

【MES】工业4.0智能制造数字化工厂(数字车间、MES、ERP)解决方案:智能工厂体系架构、系统集成以及智能设计、生产、管理、仓储物流等

工业4.0智能制造数字化工厂的解决方案&#xff0c;涵盖了智能制造的背景、企业实现智能工厂的好处、智能工厂的规划与实现方法以及系统实施模块的详细介绍。通过上汽通用凯迪拉克工厂的案例展示了智能工厂的强大能力&#xff0c;强调了数据、技术、管理、人员等关键要素在智能制…

3.【鸿蒙应用开发实战: 从入门到精通】开发入门 Hello World

1.【鸿蒙应用开发实战: 从入门到精通】开发入门 Hello World1.1 前言1.2 创建一个新项目1.2.1 打开DevEco Studio1.2.2 点击 Create Project 创建项目1.3 遗留问题1.4 总结与开发建议1.5 结束语1.1 前言 上篇博文【2.【鸿蒙应用开发实战: 从入门到精通】开发环境搭建】我们已经…

mac系统本地部署Dify步骤梳理

更换终端&#xff0c;适配步骤梳理见笔记前提&#xff1a;已安装docker desktop&#xff0c;若未安装&#xff0c;跳转至文末先安装1.Git软件准备&#xff08;1&#xff09;确认查询Git版本&#xff08;2&#xff09;如果查询不到系统会提示安装&#xff0c;点击安装即可&#…

深度学习——基于卷积神经网络实现食物图像分类【1】(datalodar处理方法)

1. 项目概述 在这个项目中&#xff0c;我们将使用PyTorch框架构建一个卷积神经网络(CNN)来实现食物图像分类任务。我们的数据集包含20种不同的食物类别&#xff0c;包括八宝粥、巴旦木、白萝卜、板栗等常见食物。本文将详细介绍从数据准备、模型构建到训练和评估的完整流程。 …

华中科大联手小米推出ReCogDrive:自动驾驶迎来“认知革命”!

1.【前言】 在开放道路中实现安全、平稳、泛化的自动驾驶&#xff0c;是智能交通领域的“圣杯”。尽管近年来 端到端自动驾驶&#xff08;End-to-End Autonomous Driving, E2E-AD&#xff09; 框架&#xff08;如 UniAD、VAD&#xff09;在 NuScenes 等基准中展现出优异表现&a…

基于 Spring AMQP 的 RabbitMQ 分布式消息系统实战

在分布式系统中&#xff0c;服务间的解耦与异步通信是关键挑战。RabbitMQ 作为一款成熟的消息中间件&#xff0c;凭借其灵活的交换器模型&#xff08;Direct/Fanout/Topic&#xff09;、可靠的消息传递机制&#xff08;持久化、确认机制&#xff09;和丰富的客户端支持&#xf…

计算机网络:天气预报

一、预期结果程序运行输入所要查询的地点&#xff0c;然后出现三个选项实时天气、未来天气、生活指数。二、实现思路&#xff08;一&#xff09;Ubuntu中利用NOWapi服务器获取访问数据api地址&#xff0c;然后创建客户端利用TCP、IPV4协议分别访问实时天气&#xff0c;未来天气…

GD32VW553-IOT OLED移植

1.前言 本来想用他自身的硬件I2C实现的&#xff0c;但是不知道为啥跑demo一点波形都没有&#xff0c;改成推挽也没有波形&#xff0c;只有初始化的电平变化&#xff0c;而且I2C的驱动库好像有点复杂&#xff0c;起始信号结束信号都得单独发的&#xff0c;没有一个全部封装好的库…

刀客doc:Instagram会成为Meta广告业务的第二曲线吗?

文/刀客doc(头条深一度精选作者)一如果现在还用“Facebook的小弟”来定义Instagram&#xff0c;多少显得有些过时了。在和一些出海品牌负责人聊天时&#xff0c;我有个很明显的感受&#xff1a;他们已经不会再把Instagram当成“附属资源”去看待。到2025年第二季度&#xff0c;…

Python日期计算完全指南:从上周五到任意日期的高效计算

引言&#xff1a;日期计算的核心价值在业务系统开发中&#xff0c;日期计算是高频且关键的需求。根据2024年企业系统调查报告&#xff1a;85%的财务系统需要计算上周五&#xff08;工资结算日&#xff09;78%的报表系统依赖周数据统计92%的供应链系统使用工作日计算65%的BI工具…