QT实现TCP通信

QT实现TCP通信案例

pro文件修改

QT       += core gui network

服务器端

widget.h代码

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer>   //服务器类
#include <QTcpSocket>   //客户端类头文件
#include <QList>    //链表容器,用于存储连接过来的客户端
#include <QMessageBox>
#include <QtDebug>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_serverBtn_clicked();void newConnection_slot();void readyRead_slot();private:Ui::Widget *ui;//定义服务器指针QTcpServer *server;//定义客户端容器QList<QTcpSocket *> clientList;
};
#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);//将服务器的newConnection信号connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);
}Widget::~Widget()
{delete ui;
}//启动服务器按钮对应的槽函数
void Widget::on_serverBtn_clicked()
{if(ui->serverBtn->text() == "启动服务器"){//启动服务器逻辑//获取ui界面上的端口号quint16 port = ui->portEdit->text().toUInt();//启动监听//函数原型:bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);if(!server->listen(QHostAddress::Any,port)){QMessageBox::information(this,"提示","服务器启动失败");return ;}else{QMessageBox::information(this,"提示","服务器启动成功");}//更新按钮文本内容ui->serverBtn->setText("关闭服务器");}else{//关闭服务器逻辑server->close();//更新按钮文本内容ui->serverBtn->setText("启动服务器");}
}void Widget::newConnection_slot()
{//QMessageBox::information(this,"提示","有新客户发来连接请求了");qDebug() << "有新客户发来连接请求了";//获取最新连接的客户端套接字//函数原型:QTcpSocket *nextPendingConnection();//参数:无//返回值:最新连接的套接字的地址QTcpSocket *s = server->nextPendingConnection();//将该套接字放入到客户端链表中即可clientList.push_back(s);//程序执行至此,一个服务器和多个客户端就已经建立了连接//当某个客户端发送消息后,该套接字就会自动发射一个readyRead信号//我们可以将该信号连接到自定义的槽函数中执行相关逻辑connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
}void Widget::readyRead_slot()
{//循环遍历所有客户端,查看哪一个客户端中有消息待读for(auto val:clientList){//判断当前客户端中是否有消息待读//函数原型:qint64 bytesAvailable() const override;//参数:无//返回值:返回当前套接字中能够被读取出来的个数,如果该个数为0,表示当前套接字数据可读if(val->bytesAvailable()){//表示当前套接字发消息了,将当前套接字消息读取出来QByteArray msg = val->readAll();//将该消息展示到ui界面上ui->listWidget->addItem(QString::fromLocal8Bit(msg));//将该消息转发给所有客户端for(auto key:clientList){key->write(msg);}}}
}

客户端

widget.h代码

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpSocket>   //客户端类
#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_connectBtn_clicked();void connected_slot();  //自定义处理connected信号的槽函数void readyRead_slot();  //自定义处理readyRead信号的槽函数void on_sendBtn_clicked();void on_disconnectBtn_clicked();void disconnected_slot();  //自定义处理disconnected信号的槽函数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);//将客户端套接字的connected的信号连接到自定义的槽函数中connect(client, &QTcpSocket::connected, this, &Widget::connected_slot);//当服务器端向客户端发来消息后,那么客户端套接字就会自动发射一个readyRead信号//我们可以将该信号连接到自定义的槽函数中处理相关逻辑connect(client, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);//将disconnected信号连接到槽函数中connect(client, &QTcpSocket::disconnected,this, &Widget::disconnected_slot);
}Widget::~Widget()
{delete ui;
}//连接服务器按钮对应的槽函数
void Widget::on_connectBtn_clicked()
{//先获取ui界面上的数据userName = ui->nameEdit->text();     //用户名QString ip = ui->ipEdit->text();       //ip地址quint16 port = ui->portEdit->text().toUInt();    //端口号//连接服务器//函数原型:virtual void connectToHost(const QString &hostName, quint16 port, OpenMode mode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol);//参数1:服务器的ip地址//参数2:服务器的端口号//返回值:无client->connectToHost(ip, port);//程序执行至此,表示已经向服务器发送连接请求了,如果成功连接服务器//那么该套接字就会自动发射一个connected的信号,我们可以将该信号连接到自定义的槽函数中处理逻辑//由于只需要连接一次,所以,可以写在构造函数中
}//自定义处理connected信号的槽函数
void Widget::connected_slot()
{QMessageBox::information(this, "提示", "连接服务器成功");//顺便向服务器发送一条消息: XXX:进入聊天室//准备消息QString msg = userName + ": 进入聊天室";qDebug() << msg;//将消息发送给服务器client->write(msg.toLocal8Bit());
}//自定义处理readyRead信号的槽函数的实现
void Widget::readyRead_slot()
{//读取套接字中的数据QByteArray msg = client->readAll();qDebug() << msg;//将消息展示到ui界面上ui->listWidget->addItem(QString::fromLocal8Bit(msg));
}//发送信息按钮对应的槽函数
void Widget::on_sendBtn_clicked()
{//获取ui界面上消息编辑器上的文本内容QString msg = userName + ": " + ui->msgEdit->text();//将消息发送给服务器qDebug() << msg;client->write(msg.toLocal8Bit());//清空编辑器中的文本内容ui->msgEdit->clear();
}//断开服务器按钮对应的槽函数
void Widget::on_disconnectBtn_clicked()
{//向服务器发送消息:XXX:离开聊天室QString msg = userName + ": 离开聊天室";qDebug() << msg;//将消息发送给服务器client->write(msg.toLocal8Bit());//将套接字与服务器断开client->disconnectFromHost();//当客户端成功与服务器断开连接后,该客户端会自动发射一个disconneted的信号//我们可以将该信号连接到自定义的槽函数中处理相关逻辑//由于只需要连接一次,所以放在构造函数中进行
}//处理disconnected信号对应的槽函数
void Widget::disconnected_slot()
{QMessageBox::information(this, "提示", "断开成功");
}

运行效果

点击关闭服务器

知识梳理

回顾TCP通信

QT中的TCP网络通信

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

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

相关文章

【Web】复现n00bzCTF2024 web题解(全)

目录 File Sharing Portal 方法一&#xff1a; 方法二&#xff1a; Focus-on-yourSELF Passwordless File Sharing Portal 附件的Dockerfile给了这么一段 # Add the cron job to the crontab RUN mkdir /etc/cron.custom RUN echo "*/5 * * * * root rm -rf /app…

uibot发送邮件:自动化邮件发送教程详解!

uibot发送邮件的操作指南&#xff1f;uibot发送邮件的两种方式&#xff1f; 在现代办公环境中&#xff0c;自动化流程的引入极大地提高了工作效率。uibot发送邮件功能成为了许多企业和个人实现邮件自动化发送的首选工具。AokSend将详细介绍如何使用uibot发送邮件。 uibot发送…

MyBatis 用法详解

文章目录 一、普通 SQL1.1 注解实现&#xff1a;1.1.1 参数传递&#xff1a;1.1.2 增&#xff08;Insert&#xff09;&#xff1a;1.1.3 删&#xff08;Delete&#xff09;&#xff1a;1.1.4 改&#xff08;Update&#xff09;&#xff1a;1.1.5 查&#xff08;Select&#xff…

贴吧软件怎么切换ip

在网络使用中&#xff0c;有时我们需要切换IP地址来满足特定的需求&#xff0c;比如需要切换贴吧软件IP以进行不同的操作。本文将介绍几种贴吧切换IP地址的方法&#xff0c;帮助用户更好地管理自己的网络身份和访问权限。 1、更换网络环境‌ 通过连接到不同的Wi-Fi网络或使用移…

微服务之间的相互调用的几种常见实现方式对比

目录 微服务之间的相互调用的几种实现方式 一、HTTP HTTP/RESTful API调用工作原理 二、RPC 设计理念与实现方式 协议与传输层 RPC远程调用工作原理 应用场景与性能考量 特点 三、Feign 设计理念与实现方式 协议与传输层 Feign调用的基本流程 Feign调用的工作原理…

钢铁行业3大改造方向 智能仪器亦起到重要作用!

钢铁企业新的改造方向主要包括超低排放改造、能效改造和数字化转型。‌这些政策旨在提升钢铁行业的环保水平、能效和智能化水平。其中智能仪器的加入&#xff0c;为钢铁企业数字化智能化自动化改造带来新的活力。 具体来说&#xff0c;到2027年&#xff0c;钢铁行业将实现以下目…

ubuntu-24.04.1 系统安装

使用VMware虚拟机上进行实现 官网下载地址&#xff1a; https://cn.ubuntu.com/download https://releases.ubuntu.com 操作系统手册&#xff1a; https://ubuntu.com/server/docs/ &#xff08;里面包含安装文档&#xff09; 安装指南&#xff08;详细&#xff09;&#xff1a…

华为云应用侧Android Studio开发

本文将介绍如何使用AndroidStudio开发APP完成与接入华为云IoTDA设备的对接&#xff0c;包括属性参数获以及取命令下发。 一、鉴权认证 应用侧需要通过IAM服务鉴权&#xff0c;获取token&#xff0c;华为账号创建 IAM 用户&#xff0c; 可以为创建的用户分配权限 认证鉴权_设…

PHP智慧餐饮新风尚点餐系统

智慧餐饮新风尚点餐系统 —— 美食与科技的完美碰撞 &#x1f37d;️ 开篇&#xff1a;智慧餐饮的崛起 在快节奏的现代生活中&#xff0c;智慧餐饮正逐渐成为我们日常的一部分。随着科技的飞速发展&#xff0c;餐饮行业也在不断创新&#xff0c;力求为顾客提供更加便捷、高效…

深信服上网行为管理AC无法注销在线用户

下图用户认证成功后无法注销 很多入网的用户都是使用的这个账号 针对单个IP强制注销也不生效 解决步骤&#xff1a; 接入管理-用户管理-用户绑定管理-用户绑定 删除绑定免认证的配置 删除后所有用户会强制注销掉&#xff0c;重新登录即可 可添加主页联系方式帮忙远程解决问…

codeforces- 973-div2----补题

1、求最小时间 思路&#xff1a;简单的模拟 木桶效应 #include<iostream> #include<algorithm> using namespace std; typedef long long ll; int dx[] { 0,1,0,-1 }; int dy[] { 1,0,-1,0 }; const ll N 2e5 5; const ll mod 1e9 7; ll a[N]; void solve…

免费又好用的保护网站WAF,基于语义引擎的waf雷池社区版推荐

为什么传统规则防护失效了&#xff1f;&#x1f914; 目前&#xff0c;大多数 Web 应用防火墙&#xff08;WAF&#xff09;依赖规则匹配来识别和阻断攻击流量。然而&#xff0c;随着 Web 攻击的低成本、复杂多样的手段和频繁爆发的高危漏洞&#xff0c;管理人员不得不频繁调整防…

pyQT5+vscode python开发环境搭建

1、下载安装python https://www.python.org/ftp/python/3.9.13/python-3.9.13-amd64.exe 注意&#xff1a;高版本python的pyQT5可能有兼容性问题,我之前装的python3.11时pyuic就不工作&#xff0c;就降级为3.9 2、安装pip 及 pyQT python -m ensurepip --default-pip pip i…

蓝桥杯【物联网】零基础到国奖之路:十六. 扩展模块之矩阵按键

蓝桥杯【物联网】零基础到国奖之路:十六. 扩展模块之矩阵按键 第一节 硬件解读第二节 CubeMX配置第三节 MDK代码 第一节 硬件解读 扩展模块和ADC模块是一摸一样的&#xff0c;插在主板上。 引脚对应关系&#xff1a; PB6-ROW1 PB7-ROW2 PB1-COLUMN1 PB0-COLUMN2 PA8-COLUMN3 …

骨传导耳机哪个牌子好?2024年度五大高分骨传导机型推荐!

骨传导耳机哪个牌子好&#xff1f;作为专业健身教练&#xff0c;我平日在训练的时候会使用骨传导耳机来听歌&#xff0c;不过&#xff0c;随着骨传导耳机热度逐渐提高&#xff0c;如今市场上骨传导耳机品牌繁多&#xff0c;类型各异&#xff0c;它们的质量差距也很大。很多网红…

【Java】多线程代码案例

多线程代码案例 单例模式初步了解饿汉模式懒汉模式线程安全问题分析存在的问题 生产者消费者模型初识生产者消费者模型初识阻塞队列生产者消费者模型的意义BlockingQueue阻塞队列模拟实现 定时器初识计时器初识Timer类初识 schedule() 方法简易定时器的实现思路讲解代码书写 线…

耳机座接口会被TYPE-C取代吗?

耳机座接口&#xff0c;即传统的3.5mm耳机插孔&#xff0c;一直以来都是音频设备的标准配置。然而&#xff0c;随着科技的发展和用户需求的变化&#xff0c;TYPE-C接口逐渐崭露头角&#xff0c;成为许多设备的主流选择。这一趋势引发了一个重要问题&#xff1a;耳机座接口会被T…

Collection 集合框架

Collection 集合框架 各类集合 Set TreeSet 基于红黑树实现&#xff0c;支持有序性操作&#xff0c;例如根据一个范围查找元素的操作。但是查找效率不如 HashSet&#xff0c;HashSet 查找的时间复杂度为 O(1)&#xff0c;TreeSet 则为 O(logN)。 HashSet 基于哈希表实现&…

php常用的注释符号

如果没有安装vscode和小皮&#xff0c;请点击下方链接安装&#xff1a; Vscode、小皮面板安装-CSDN博客 在学习php过程中&#xff0c;肯定少不了注释&#xff0c;也可以理解为备注的信息&#xff0c;来提醒自己这段代码有什么用&#xff0c;是什么意思等&#xff0c;接下来就介…

【Redis】网络模型(day10)

在本篇文章中&#xff0c;主要是对五种网络模型进行一个简单的介绍&#xff0c;然后对Redis4.0和6.0的网络模型进行一个概述。 用户空间和内核空间 在Linux系统上&#xff0c;分为用户空间、内核空间和硬件设备。硬件设备主要包括CPU、内存、网卡等物体&#xff0c;内核应用去…