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);
}

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

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

相关文章

point transformer v3复现及核心代码详解

point transformer v3复现及核心代码详解 1. 复现1.1 复现1.2 数据预处理1.3 跑通 2. 核心代码详解2.1 读取数据2.2 dataloder2.3 模型读取数据的逻辑2.4 forward2.4.1 Point2.4.2 backbone2.4.2.1 point.serialization2.4.2.2 稀疏化2.4.2.3 embedding2.4.2.4 encoder 1. 复现…

Emlog程序屏蔽用户IP拉黑名单插件

插件介绍 在很多时候我们需要得到用户的真实IP地址&#xff0c;例如&#xff0c;日志记录&#xff0c;地理定位&#xff0c;将用户信息&#xff0c;网站数据分析等,其实获取IP地址很简单&#xff0c;感兴趣的可以参考一下。 今天给大家带来舍力写的emlog插件&#xff1a;屏蔽…

wakenet尾迹

1、数据集介绍SWIM_Dataset_1.0.0 1.1标注文件介绍 标注文件介绍&#xff0c; 第一种&#xff1a;角度和框的坐标 <annotation><folder>Positive</folder><filename>00001</filename>文件名字<format>jpg</format>图片后缀<s…

自掘坟墓?开源正在卷爆程序员!

前端训练营&#xff1a;1v1私教&#xff0c;终身辅导计划&#xff0c;帮你拿到满意的 offer。 已帮助数百位同学拿到了中大厂 offer Hello&#xff0c;大家好&#xff0c;我是 Sunday。 今天这篇文章其实我想了好久&#xff0c;因为这并不是一个 和光同尘 的话题&#xff0c;它…

第143天:内网安全-权限维持自启动映像劫持粘滞键辅助屏保后门WinLogon

案例一&#xff1a; 权限维持-域环境&单机版-自启动 自启动路径加载 路径地址 C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\StartMenu\Programs\Startup\ ##英文C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\开始菜单\程序\启动\ ##中文…

OpenHarmony鸿蒙( Beta5.0)智能窗户通风设备开发详解

鸿蒙开发往期必看&#xff1a; 一分钟了解”纯血版&#xff01;鸿蒙HarmonyOS Next应用开发&#xff01; “非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线&#xff01;&#xff08;从零基础入门到精通&#xff09; “一杯冰美式的时间” 了解鸿蒙HarmonyOS Next应用开发路…

如何逆转Instagram账号流量减少?实用技巧分享

Instagram作为全球十大社媒之一&#xff0c;不仅是个人分享生活的平台&#xff0c;还是跨境卖家进行宣传推广和客户开发的关键工具。在运营Instagram的过程中&#xff0c;稍有不慎就容易出现账号被限流的情况&#xff0c;对于账号状态和运营工作的进行都十分不利。 一、如何判断…

isis与ospf高级属性

文章目录 前言一、基础配置(配置各设备的IP地址)二、配置各设备的ospf与isis三、检查ospf与isis邻居是否建立成功1.实现快速重路由2.流量过滤方法3.引入默认路由4.配置等价路由 前言 在下面实验中&#xff0c;蓝色区域运行ospf&#xff0c;为了控制ospf的lsdb数量&#xff0c;…

vue页面使用自定义字体

一、准备好字体文件 一般字体问价格式为 .tff&#xff0c;可以去包图网等等网站去下载&#xff0c;好看的太多了&#xff01;&#xff01;&#xff01; 下载下来就是单个的 .tff文件&#xff0c;下载下来后可以进行重命名&#xff0c;但是不要改变他的后缀名&#xff0c;我把他…

【c++】类和对象详解

✅博客主页:爆打维c-CSDN博客​​​​​​ &#x1f43e; &#x1f539;分享c语言知识及代码 来都来了! 点个赞给博主个支持再走吧~&#xff01; 一.类的定义 &#xff08;1&#xff09;类定义格式 class为类定义的关键字&#xff0c;定义一个类格式如下: class 类名{//代码…

turtle.circle() 函数绘制弧形规律助记图 ← Python

【Python 之 turtle.circle() 函数定义】 定义&#xff1a;turtle.circle(radius, extent)作用&#xff1a;根据半径 radius 绘制 extent 角度的弧形参数&#xff1a;radius &#xff1a;弧形半径当 radius 值为正数时&#xff0c;圆心在当前位置/小海龟左侧。当 radius 值为负…

9月美联储决策前哨战——美国CPI数据来袭

随着本周关键CPI数据的即将发布&#xff0c;市场正翘首以待&#xff0c;这将是美联储在9月17日至18日议息会议前获取的最后一块重要经济拼图。鉴于美联储官员已进入传统的政策静默期&#xff0c;8月份的CPI报告无疑将成为交易员们评估未来货币政策走向的重要标尺。 欧洲央行降…

[000-01-002].第03节:Git基础命令

我的博客大纲 我的GIT学习大纲 1、Git的常用命令 2、Git操作步骤&#xff1a; 2.1.操作Git第一步&#xff1a;设置全局的用户签名 1.设置用户名&#xff1a; 格式&#xff1a;git config --global user.name 用户名命令&#xff1a;git config --global user.name root 2.设置…

Taro + Vue 的 CSS Module 解决方案

一、开启模块化配置 Taro 中内置了 CSS Modules 的支持&#xff0c;但默认是关闭的。如果需要开启使用&#xff0c;请先在编译配置中添加如下配置&#xff1a; weapp: {module: {postcss: {// css modules 功能开关与相关配置cssModules: {enable: true, // 默认为 false&…

如何解决户用光伏项目管理难题?

户用光伏作为分布式能源的重要组成部分&#xff0c;正迎来前所未有的发展机遇。户用光伏项目的复杂性和多样性也给项目管理带来了诸多挑战&#xff0c;包括客户分散、安装周期长、运维难度大、数据监控不及时等问题。为解决这些难题&#xff0c;构建一套高效、智能的户用光伏业…

SpringMVC基于注解使用:国际化

01-国际化介绍 首先在bootstrap下载个页面 下载后把登录页面的代码粘上去 然后再登录页面代码上有些超链接需要再spring-mvc.xml里面配置下&#xff0c;登录页面才能正常显示 配置静态资源 国际化-根据浏览器语言国际化 现在是中文的情况&#xff0c;要改为英文 1.配置下属…

OFDM信号PARP的CCDF图

文章目录 引言代码代码疑难解答参考文献 引言 本书主要参考了文献1&#xff0c;但实际上该书中符号和表述的错误非常多&#xff08;只能说棒子是这样的&#xff09;&#xff1b;同时因为发表时间的关系&#xff0c;很多MATLAB代码进行了更新&#xff0c;原书提供的代码已经无法…

Flutter中自定义气泡框效果的实现

在用户界面的设计中&#xff0c;气泡框&#xff08;Bubble&#xff09;是一种非常有效的视觉工具&#xff0c;它可以用来突出显示信息或提示用户。气泡框广泛应用于聊天应用、通知提示等场景。在 Flutter 中&#xff0c;虽然有很多现成的气泡框组件&#xff0c;但如果你想要更多…

使用豆包MarsCode 编写 Node.js 全栈应用开发实践

以下是「豆包MarsCode 体验官」优秀文章&#xff0c;作者狼叔。 欢迎更多用户使用豆包MarsCode 并分享您的产品使用心得及反馈、创意项目开发等&#xff0c;【有奖征集&#xff5c;人人都是豆包MarsCode 测评官&#xff01;】活动正在火热进行中&#xff0c;欢迎大家投稿参加&a…

跨部门SOP与统一知识库:打破信息孤岛,促进团队协作

引言&#xff1a; 在当今这个快速变化且高度竞争的商业环境中&#xff0c;企业面临着前所未有的挑战&#xff0c;其中之一便是如何高效地跨越部门界限&#xff0c;实现无缝协作。传统的组织结构往往导致信息孤岛的出现&#xff0c;不同部门间流程不一致、信息不共享&#xff0…