通过QT进行服务器和客户端之间的网络通信
客户端
client.pro
#-------------------------------------------------
#
# Project created by QtCreator 2024-07-02T14:11:20
#
#-------------------------------------------------QT += core gui network #网络通信greaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = client
TEMPLATE = app# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as 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 you use 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\widget.cppHEADERS += widget.hFORMS += widget.ui
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpSocket>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();void InitClient();private slots:void on_connect_bt_clicked();void on_send_bt_clicked();void OnReadData();private:Ui::Widget *ui;QTcpSocket *m_pSocket;
};#endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.InitClient();w.show();return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug> //Qt 提供的输出调试信息的工具。
#include <QHostAddress>Widget::Widget(QWidget *parent) : //Widget类继承自QWidgetQWidget(parent),ui(new Ui::Widget) //通过ui对象初始化界面布局
{ui->setupUi(this);m_pSocket = NULL; //初始化m_pSocket为NULL
}Widget::~Widget() //析构函数释放了ui对象。
{delete ui;
}void Widget::InitClient() //设置界面初始状态,创建串口对象
{qDebug() << "Widget::InitClient() enter";if (NULL == m_pSocket){m_pSocket = new QTcpSocket(this); //QTcpSocket是Qt提供的用于TCP网络通信的类connect(m_pSocket, SIGNAL(readyRead()), this, SLOT(OnReadData()));//readyRead()当socket接收到新的数据时发出的信号,SIGNAL()是一个宏,将信号转换为字符串形式。this是信号的发送者。//当m_pSocket对象接收到数据时,会触发readyRead()信号,然后调用当前类的OnReadData()槽函数来处理这些接收到的数据}qDebug() << "Widget::InitClient() exit";
}void Widget::on_connect_bt_clicked() //当按钮connect_bt被点击时触发
{qDebug() << "Widget::on_connect_bt_clicked() enter";QString strIP = ui->ip_edit->text(); //获取用户输入的IP地址QString strPort = ui->port_edit->text();qDebug() << strIP << " " << strPort;if (strIP.length() == 0 || strPort.length() == 0) //检查用户输入的有效性,如果IP或端口号为空,则输出错误信息并返回{qDebug() << "input error";return;}if (NULL == m_pSocket) //检查m_pSocket是否为NULL,如果是则输出错误信息并返回{qDebug() << "socket error";return;}m_pSocket->connectToHost(QHostAddress("127.0.0.1"), strPort.toShort());//使用m_pSocket->connectToHost()连接到指定的主机地址(这里是本地地址 "127.0.0.1")和端口号if (m_pSocket->waitForConnected(3000))//使用m_pSocket->waitForConnected(3000)等待连接建立,超时时间为3000毫秒(3秒){qDebug() << "connect ok";}else{qDebug() << "connect error";}qDebug() << "Widget::on_connect_bt_clicked() exit";
}void Widget::on_send_bt_clicked()
{qDebug() << "Widget::on_send_bt_clicked() enter";QString strData = ui->send_edit->text();if (strData.length() == 0){qDebug() << "input error";return;}if (NULL == m_pSocket){qDebug() << "socket error";return;}m_pSocket->write(strData.toStdString().data()); //发送字符串形式的数据到已连接的服务器端qDebug() << "Widget::on_send_bt_clicked() exit";
}void Widget::OnReadData()
{QByteArray arr = m_pSocket->readAll(); //读取所有接收到的数据,并将其存储arr中qDebug() << arr;
}
widget.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>Widget</class><widget class="QWidget" name="Widget"><property name="geometry"><rect><x>0</x><y>0</y><width>692</width><height>468</height></rect></property><property name="windowTitle"><string>Widget</string></property><widget class="QLabel" name="label"><property name="geometry"><rect><x>50</x><y>60</y><width>72</width><height>15</height></rect></property><property name="text"><string>ip</string></property></widget><widget class="QLineEdit" name="ip_edit"><property name="geometry"><rect><x>100</x><y>60</y><width>181</width><height>21</height></rect></property></widget><widget class="QLabel" name="label_2"><property name="geometry"><rect><x>40</x><y>100</y><width>72</width><height>15</height></rect></property><property name="text"><string>port</string></property></widget><widget class="QLineEdit" name="port_edit"><property name="geometry"><rect><x>100</x><y>100</y><width>181</width><height>21</height></rect></property></widget><widget class="QPushButton" name="connect_bt"><property name="geometry"><rect><x>350</x><y>90</y><width>93</width><height>28</height></rect></property><property name="text"><string>connect</string></property></widget><widget class="QPushButton" name="send_bt"><property name="geometry"><rect><x>350</x><y>150</y><width>93</width><height>28</height></rect></property><property name="text"><string>send</string></property></widget><widget class="QLineEdit" name="send_edit"><property name="geometry"><rect><x>100</x><y>160</y><width>181</width><height>21</height></rect></property></widget></widget><layoutdefault spacing="6" margin="11"/><resources/><connections/>
</ui>
服务器
server.pro
#-------------------------------------------------
#
# Project created by QtCreator 2024-07-02T09:20:48
#
#-------------------------------------------------QT += core gui networkgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = server
TEMPLATE = app# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as 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 you use 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\widget.cppHEADERS += widget.hFORMS += widget.ui
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();void InitServer();private slots:void OnNewConnection();void OnReadyData();void on_listen_bt_clicked();private:Ui::Widget *ui;QTcpServer *m_pServer;
};#endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.InitServer();w.show();return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QHostAddress>
#include <QTcpSocket>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);m_pServer = NULL;
}Widget::~Widget()
{delete ui;
}void Widget::InitServer()
{qDebug() << "Widget::InitServer() enter";if (NULL == m_pServer){m_pServer = new QTcpServer(this);connect(m_pServer, SIGNAL(newConnection()), this, SLOT(OnNewConnection()));}qDebug() << "Widget::InitServer() exit";
}void Widget::OnNewConnection()
{qDebug() << "new connection";QTcpSocket *pTmp = m_pServer->nextPendingConnection(); //获取下一个挂起的连接if (NULL != pTmp){connect(pTmp, SIGNAL(readyRead()), this, SLOT(OnReadyData()));//当这个客户端socket有数据可读时,就会调用OnReadyData()函数}
}void Widget::OnReadyData()
{qDebug() << "read data";QTcpSocket *pTmp = (QTcpSocket *)sender(); //获取信号的发送者if (NULL == pTmp){qDebug() << "socket error";return;}QByteArray arr = pTmp->readAll(); //读取所有接收到的数据//qDebug() << arr;QString strData = ui->textEdit->toPlainText(); //将接收到的数据显示在界面中strData.append("recv : "); //追加数据recv :strData.append(arr);strData.append("\n");ui->textEdit->setText(strData);pTmp->write(arr); //将接收到的数据原样发送回客户端
}void Widget::on_listen_bt_clicked()
{qDebug() << "Widget::on_listen_bt_clicked() enter";if (NULL == m_pServer){return;}QString strIP = ui->ip_edit->text();QString strPort = ui->port_edit->text();if (strIP.length() == 0 || strPort.length() == 0){qDebug() << "input error";return;}bool bRet = m_pServer->listen(QHostAddress(strIP), strPort.toShort()); //监听指定的IP地址和端口号if (bRet == true){qDebug() << "server listen ok";}qDebug() << "Widget::on_listen_bt_clicked() enter";
}
widget.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>Widget</class><widget class="QWidget" name="Widget"><property name="geometry"><rect><x>0</x><y>0</y><width>893</width><height>629</height></rect></property><property name="windowTitle"><string>Widget</string></property><widget class="QLabel" name="label"><property name="geometry"><rect><x>80</x><y>60</y><width>72</width><height>15</height></rect></property><property name="text"><string>ip</string></property></widget><widget class="QLineEdit" name="ip_edit"><property name="geometry"><rect><x>140</x><y>60</y><width>221</width><height>21</height></rect></property></widget><widget class="QLineEdit" name="port_edit"><property name="geometry"><rect><x>140</x><y>100</y><width>221</width><height>21</height></rect></property></widget><widget class="QLabel" name="label_2"><property name="geometry"><rect><x>80</x><y>100</y><width>72</width><height>15</height></rect></property><property name="text"><string>port</string></property></widget><widget class="QPushButton" name="listen_bt"><property name="geometry"><rect><x>400</x><y>100</y><width>93</width><height>28</height></rect></property><property name="text"><string>listen</string></property></widget><widget class="QTextEdit" name="textEdit"><property name="geometry"><rect><x>60</x><y>190</y><width>761</width><height>401</height></rect></property></widget></widget><layoutdefault spacing="6" margin="11"/><resources/><connections/>
</ui>
测试
相关文章:

通过QT进行服务器和客户端之间的网络通信
客户端 client.pro #------------------------------------------------- # # Project created by QtCreator 2024-07-02T14:11:20 # #-------------------------------------------------QT core gui network #网络通信greaterThan(QT_MAJOR_VERSION, 4): QT widg…...

【STM32 HAL库】DMA+串口
DMA 直接存储器访问 DMA传输,将数据从一个地址空间复制到另一个地址空间。-----“数据搬运工”。 DMA传输无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场,它是通过硬件为RAM和IO设备开辟一条直接传输数据的通道,…...
C#类型基础Part2-对象判等
C#类型基础Part2-对象判等 参考资料引用类型判等简单值类型判等复杂值类型判等 参考资料 《.NET之美-.NET关键技术深入解析》 引用类型判等 先定义两个类型,它们代表直线上的一个点,一个是引用类型class,一个是值类型struct public class…...
13.CSS 打印样式表 悬停下划线动画
CSS 打印样式表 虽然我们不经常从网上实际打印内容,但打印样式表不应被忽视。它们可以用来确保你的网站内容以一种易读和适合打印的方式呈现。这里有一个简单的、独特的打印样式表,你可以用它作为自己的基础: media print {page {size: A4;}body {margin: 0;padding: 0;}body, …...
C#基础:数据库分表的好处和实现方式
一、分表的好处: 1.提升查询速度:分表筛选后再拼接,而不是查大表,速度会显著提升 2.管理容易:根据业务需求,通常会按照时间或者空间来分表 3.提高并发性:降低锁竞争和查询阻塞的风险…...

基于3D开发引擎HOOPS平台的大型三维PLM系统的设计、开发与应用
产品生命周期管理(Product Lifecycle Management,PLM)系统在现代制造业中扮演着至关重要的角色。随着工业4.0和智能制造的推进,PLM系统从最初的CAD和PDM系统发展到现在的全面集成、协作和智能化的平台。本文将探讨基于HOOPS平台的…...

学习React(描述 UI)
React 是一个用于构建用户界面(UI)的 JavaScript 库,用户界面由按钮、文本和图像等小单元内容构建而成。React 帮助你把它们组合成可重用、可嵌套的 组件。从 web 端网站到移动端应用,屏幕上的所有内容都可以被分解成组件。在本章…...

mysql字符类型字段设置默认值为当前时间
-- 2024-07-22 10:22:20 select (DATE_FORMAT(CURRENT_TIMESTAMP, %Y-%m-%d %H:%i:%s)); ALTER TABLE tablename MODIFY COLUNN CREATE_DATE varchar (23) DEFAULT(DATE_FORMAT(CURRENT_TIMESTAMP, %Y-%m-%d %H:%i:%s)) COMMENT "创建日期;...

java题目之数字加密以及如何解密
public class Main6 {public static void main(String[] args) {// 某系统的数字密码(大于0),比如1983,采用加密方式进行传输//定义了一个静态数组int []arr{1,9,8,3};//1.加密//先给每位数加上5for (int i 0; i <arr.length …...

Linux基于CentOS7【yum】【vim】的基础学习,【普通用户提权】
目录 yum生态 什么是yum yum是如何得知目标服务器的地址和下载链接 vim vim模式 命名模式 光标移动 插入模式 i键插 a键插 o键插 底行模式 批量化注释 批量化去注释 创建vim配置文件 例子 高亮功能: 缩进功能: 符号位自动补齐功能…...

盛元广通实验室自动化生物样本库质量控制管理系统
随着我国生物医学研究的不断深入和精准医疗的快速发展,对高质量生物样本的需求日益增长。近年来,我国生物样本库建设取得了显著进展。各级政府、高校和医院纷纷投入资源建设生物样本库,推动了生物样本资源的有效整合和利用。生物样本库的质量…...

Java | 自制AWT单词猜一猜小游戏(测试版)
目录 游戏标题 开发过程 开发想法 技术栈 代码呈现 导包 核心代码 游戏标题 探索知识的迷宫,体验自制AWT单词猜一猜小游戏 在数字时代,学习可以是多彩的,游戏可以是智慧的。我们自豪地推出“单词猜猜猜”是一款结合了教育与娱乐的自制…...

docker搭建ES 8.14 集群
参考:【docker搭建es8集群kibana】_docker 安装生产级 es 8.14 集群-CSDN博客 1、之前已搭建一台单机版的dockerES集群 参见 Elasticsearch docker 安装_docker 安装es8.14.3-CSDN博客 2、现在需要重新搭建为docker ES集群 准备新搭建3个点 一、准备工作 提前开…...
自定义特征的智能演进:Mojo模型中的动态特征选择控制
自定义特征的智能演进:Mojo模型中的动态特征选择控制 在机器学习领域,特征选择是提升模型性能和泛化能力的关键步骤。Mojo模型,作为一种高效的模型部署方式,其对特征的动态选择和控制能力是实现高级机器学习应用的重要特性。本文…...
Git->Git生成patch和使用patch
生成patch git format-patch -1 HEAD -o "输出目录"format-patch:用于生成补丁文件-1:-1 表示最近一次提交,-2 表示生成最近两次提交的补丁。HEAD:HEAD 指向当前分支的最新提交-o:指定生成的补丁文件的输出…...
开发面试算法题求教
在《无尽的拉格朗日》中,有许多不同的星系建筑物。每个星系建筑物的等级不同,带来的影响力也不同。 已知宇宙可以抽象为一个无穷大的平面直角坐标系,现在给定了每个星系建筑物的所在坐标(xi,yi)和它的影响力ri,距离其切比雪夫距离…...
OpenStack中nova的架构
1.1 nova-api 负责接收和相应客户的API调用。 1.2 compute core nova-schedule 负责决定在哪个计算节点运行虚拟机。 nova-compute 通过调用Hypervisor实现虚拟机生命周期的管理。一般运行在计算节点。 hypervisor 对虚拟机进行硬件虚拟化的管理软件ÿ…...

力扣高频SQL 50题(基础版)第五题
文章目录 力扣高频SQL 50题(基础版)第五题1683. 无效的推文题目说明:思路分析:实现过程:结果截图: 力扣高频SQL 50题(基础版)第五题 1683. 无效的推文 题目说明: 表&a…...

Air780EP- AT开发-阿里云应用指南
简介 使用AT方式连接阿里云分为一机一密和一型一密两种方式,其中一机一密又包括HTTP认证二次连接和MQTT直连两种方式 关联文档和使用工具: AT固件获取在线加/解密工具阿里云平台 准备工作 Air780EP_全IO开发板一套,包括天线SIM卡࿰…...

【中项】系统集成项目管理工程师-第4章 信息系统架构-4.4数据架构
前言:系统集成项目管理工程师专业,现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试,全称为“全国计算机与软件专业技术资格(水平)考试”&…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...

Axure 下拉框联动
实现选省、选完省之后选对应省份下的市区...