Qt TCP和UDP通信及线程介绍

一.UDP介绍

UDP(User Datagram Protocol,用户数据报协议)
UDP是一个轻量级、不可靠、面向数据报的、无连接的协议,多用于可靠性要求不严格,不是非常重要的传输。

QUdpSocket类继承自QAbstractSocket,用来发送和接收UDP数据报,”Socket”即套接字,套接字即IP地址+端口号。其中IP地址指定了网络中的一台主机,二端口号则指定了该主机上的一个网络程序,使用套接字即可实现网络上的两个应用程序之间的通信。

QUdpSocket支持IPv4广播,要广播数据报,则只需发送到一个特殊的地址QHostAddress::Broadcast(即255.255.255.255),数据报一般建议发送字节数小于512字节。端口号选择1024-65535(1024以下的常用作保留端口号,如FTP常用端口号21,Telnet常用端口号23,DNS域名服务器常用端口53等)。

发送端

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);m_sender=new QUdpSocket(this);}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pushButton_clicked()
{QByteArray dataGram=ui->lineEdit->text().toUtf8();m_sender->writeDatagram(dataGram.data(),dataGram.size(),QHostAddress::Broadcast,6666);}

接收端

#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);m_receiver=new QUdpSocket(this);m_receiver->bind(6666,QUdpSocket::ShareAddress);connect(m_receiver,&QUdpSocket::readyRead,this,&MainWindow::processData);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::processData()
{QString strData;//有未处理的数据包while(m_receiver->hasPendingDatagrams()){QByteArray dataGram;dataGram.resize(m_receiver->pendingDatagramSize());m_receiver->readDatagram(dataGram.data(),dataGram.size());ui->label_2->setText(dataGram);}
}

二.TCP介绍

TCP(Transmission Control Protocol,传输控制协议)

TCP是一个用于数据传输的地城网络协议,多个网络协议包括(HTTP和FTP都是基于TCP协议),TCP是面向数据流和连接的可靠的传输协议。

QTcpSocket继承自QAbstractSocket,与QUdpSocket传输的数据报不同的是,QTcpSocket传输的是连续的数据流,尤其适合连续的数据传输,TCP一般分为客户端和服务端,即C/S (Client/Server模型)。

QTcpSocket代表了两个独立的数据流,一个用来读取数据,一个用来写入数据,分别采用QTcpSocket::read()及QTcpSocket::write()操作,读取数据前先调用QTcpSocket::bytesAvailable来确定已有足够的数据可用。

QTcpServer处理客户端的连接,可通过QTcpServer::listen()监听客户端发来的连接请求,每当有客户端连接时会发射newConnection()信号,QTcpSocket可用于读取客户端发来的数据报,亦可发送数据报。

客户端

#include "mainwindow.h"
#include "ui_mainwindow.h"const int gTcpPort =8888;MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);m_tcpSocket=new QTcpSocket(this);//socket有数据来了,做处理connect(m_tcpSocket,&QTcpSocket::readyRead,this,&MainWindow::onReadMessage);connect(m_tcpSocket,SIGNAL(SocketError(QAbstractSocket::SocketError)),this,SLOT(onDisplayError(QAbstractSocket::SocketError)));ui->lineEdit_host->setText("127.0.0.1");ui->lineEdit_port->setText(QString::number(gTcpPort));}void MainWindow::onReadMessage()
{//读取信息QByteArray bt;bt.resize( m_tcpSocket->bytesAvailable());m_tcpSocket->read(bt.data(),bt.size());ui->label_receive->setText(bt);
}void MainWindow::onDisplayError(QAbstractSocket::SocketError error)
{//显示错误信息qDebug()<<"socketError:"<<error<<endl<<m_tcpSocket->errorString();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_pushButton_connect_clicked()
{//终止socketm_tcpSocket->abort();//connectToHost(IP,Port)m_tcpSocket->connectToHost(ui->lineEdit_host->text(),ui->lineEdit_port->text().toInt());}void MainWindow::on_pushButton_send_clicked()
{m_tcpSocket->write(ui->lineEdit_send->text().toUtf8());m_tcpSocket->flush();
}

服务端

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QDebug>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);m_tcpserver=new QTcpServer(this);//开始监听客户端发来的请求if(!m_tcpserver->listen(QHostAddress::Any,8888)){qDebug()<<m_tcpserver->errorString();close();}connect(m_tcpserver,&QTcpServer::newConnection,this,&MainWindow::onNewConnect);connect(m_tcpserver,&QTcpServer::newConnection,this,&MainWindow::onsendMessage);}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::onNewConnect()
{//客户端新的连接处理//当前连接的对象m_tcpsocket=m_tcpserver->nextPendingConnection();//如果断开连接自动销毁资源connect(m_tcpsocket,&QTcpSocket::disconnected,this,&QTcpSocket::deleteLater);//socket有数据时,会发射readRead信号connect(m_tcpsocket,&QTcpSocket::readyRead,this,&MainWindow::onReadMessage);
}void MainWindow::onsendMessage()
{//给客户端回馈一个信息QString str="你好,客户端!";m_tcpsocket->write (str.toUtf8());ui->label->setText("发送数据成功");}void MainWindow::onReadMessage()
{//有数据可以读时//字节数组QByteArray bt = m_tcpsocket->readAll();ui->label_Read->setText(bt);}

三.多线程编程

在Qt中进行多线程编程时,通常需要使用锁来保证共享资源的同步访问,防止多个线程同时访问导致数据的不一致性或者竞争条件的发生。Qt提供了QMutex、QMutexLocker、QReadWriteLock等类来实现锁的功能。

QMutex是最基本的锁类,可以使用lock()方法进行锁定,使用unlock()方法进行解锁。QMutexLocker是一个自动解锁类,可以避免因忘记解锁而导致的死锁问题。QReadWriteLock提供了读写锁的功能,可以允许多个线程同时读取数据,但只允许一个线程写数据。

以下是一个使用QMutex进行多线程编程的示例:

#include <QThread>
#include <QMutex>
#include <QDebug>class Worker : public QThread
{
public:void run() override{mutex.lock();qDebug() << "Thread ID:" << currentThreadId() << " is working...";mutex.unlock();}private:QMutex mutex;
};int main(int argc, char *argv[])
{QCoreApplication app(argc, argv);Worker worker1;Worker worker2;worker1.start();worker2.start();worker1.wait();worker2.wait();return app.exec();
}

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

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

相关文章

STM32MP135裸机编程:支持内存非对齐访问

0 前言 使用stm32官方可视化初始化代码生成工具STM32CubeMX生成的工程GCC编译选项默认不支持非对齐访问&#xff0c;在我们进行非对齐的访问时就会进入数据异常中断DAbt中。为了解决这一问题&#xff0c;我们需要在GCC编译选项中加上一处配置。 1 操作方法 右键STM32CubeIDE…

【Linux】:重定向和缓冲区

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家带来关于重定向和缓冲区的相关知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精…

Paddle 打包部署

PaddleOCR 打包部署exe 心酸历程 PaddleOCR部署exe模式PaddleOCR安装到本地(稍后有时间再写)PaddleOCR打包过程异常问题记录&#xff01;&#xff01;&#xff01;&#xff01;No such file or directory: D:\\py_project\\paddleOCR\\dist\\paddleOCR\\_internal\\paddleocr\\…

Excel自动化工具-工作簿中sheet页合并-可自行选择需要处理的工作簿

宝子们可以选择直接下载文章顶部资源包【Excel自动化工具-工作簿中sheet页合并.xlsm】&#xff08;或者在博主的资源里下载&#xff09;&#xff0c;该资源功能为&#xff1a;合并sheet页 或者也可以自己编写宏代码&#xff0c;文章最后有附上源代码 没有office excel 的宝子…

linux之find指令基础

目录 前言一、find .二、find xxx -name "*.c"三、组合查找文件名四、find . -type f五、find . -maxdepth 2 -type f六、find . -type f -perm 777七、find . -type f -name "*.txt" ! -perm 777八、借助-exec命令参考链接 前言 testfind下 check1.c ch…

《乡土中国》重新审视自己的故乡,再出发

《乡土中国》重新审视自己的故乡&#xff0c;再出发 费孝通(1910—2005)&#xff0c;中国社会学家、人类学家。被誉为中国社会学和人类学的奠基人之一。江苏吴江人。1980年获国际应用人类学会马林诺斯基荣誉奖。1981年获英国皇家人类学会赫胥黎奖章。代表作有《乡土中国》《江村…

【周末闲谈】Stable Diffusion会魔法的绘画师

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️Python】 文章目录 前言Stable Diffusion介绍 使用ComfyUI 和 WebUIComfyUIWebUI 配置需求 Stable Diffusion资源分享吐司AiAUTOMATIC1111Civitai绘世整合包Nenly同学stability.ai 前言 在很早之前&…

【数学建模】2005建模A题:长江水质综合评价与预测

数据的无量纲化处理 数据的无量纲化处理是一种统计学中的预处理技术&#xff0c;主要用于消除数据中的量纲影响&#xff0c;使得不同单位或量级的指标可以相互比较和结合。无量纲化通过调整数据的范围或尺度&#xff0c;使得数据集中的每个特征或变量处于相似的数值区间内。以…

【React】Google 账号之个性化一键登录按钮功能

“使用 Google 帐号登录”功能可快速管理网站上的用户身份验证。用户登录 Google 账号、表示同意&#xff0c;并安全地与平台共享其个人基础资料信息。 官方文档&#xff1a;链接 一、获取 Google API 客户端 ID 打开 Google API 控制台 中的凭据页面 创建或选择 Google API 项…

网络分层及通信过程

网络分层体系 主流的理论体系中主要包含三种网络分层模型&#xff0c;即ISO的七层网络模型、TCP/IP的四层网络模型以及结合两种模型优点的五层网络模型&#xff0c;关于网络模型&#xff0c;主要起到对网络体系的一个整体认识&#xff0c;作为网络知识学习的开始&#xff0c;这…

【并发编程】进程 线程 协程

进程&#xff08;Process&#xff09;、线程&#xff08;Thread&#xff09;和协程&#xff08;Coroutine&#xff09;构成了计算机科学中实现任务并发执行的三种核心抽象机制。通常&#xff0c;为了提高程序的执行效率&#xff0c;开发者会根据应用场景和性能需求&#xff0c;…

Linux对文件访问的基本权限

文件权限控制对文件的访问。 有三种权限类别可应用&#xff1a;读取、写入和执行。 权限对文件和目录的影响&#xff1a; 权限 对文件的影响 对目录的影响 r读取 可以读取文件的内容 可以列出目录的内容 w写入 可以更改文件的内容 可以创建或删除目录中任一文件 x执行…

对照ui图进行大屏幕适配,echerts适配

1.先找到ui图&#xff0c;我这边是1920*1080的屏幕进行的设计 2.在界面找到跟样式的字体大小&#xff0c;进行设置&#xff0c;一般ui设置字体大小便可 3.在js中写入原生js代码 function adapter() {//获取布局视口宽度&#xff0c;布局视口设备横向独立像素值const dpWidth…

【算法专题】快速排序

1. 颜色分类 75. 颜色分类 - 力扣&#xff08;LeetCode&#xff09; 依据题意&#xff0c;我们需要把只包含0、1、2的数组划分为三个部分&#xff0c;事实上&#xff0c;在我们前面学习过的【算法专题】双指针算法-CSDN博客中&#xff0c;有一道题叫做移动零&#xff0c;题目要…

JAVA NIO组件之Buffer详解

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

Highlight.js示例

图例 代码在图片后面 点赞❤️关注&#x1f64f;收藏⭐️ 源代码 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"…

7.14实训

当我开始学习各种杀毒软件时&#xff0c;我逐渐意识到信息安全在现代社会中的重要性和复杂性。杀毒软件不仅仅是简单的安装和运行&#xff0c;它涉及到广泛的知识领域&#xff0c;包括计算机网络、恶意软件分析、加密技术等等。在这个过程中&#xff0c;我收获了许多宝贵的经验…

代码随想录算法训练营第30天|LeetCode 452. 用最少数量的箭引爆气球、435. 无重叠区间、763.划分字母区间

1. LeetCode 452. 用最少数量的箭引爆气球 题目链接&#xff1a;https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/description/ 文章链接&#xff1a;https://programmercarl.com/0452.用最少数量的箭引爆气球.html 视频链接&#xff1a;https://www…

Java 线程池详解

序言 在高并发编程中&#xff0c;线程池是一个非常重要的组件。它不仅能够有效地管理和复用线程资源&#xff0c;还可以提升应用程序的性能和稳定性。本文将详细介绍Java中的线程池机制&#xff0c;以及如何正确地使用线程池。 一、什么是线程池 线程池是一组已经初始化并等…

索引结构与检索原理

一、mysql索引结构 1.BTree索引 [检索原理] 左边列的表格&#xff08;真实数据&#xff09;&#xff0c;右边对应一棵树&#xff0c;树的管度越来越管查询越快。 以下图表的名称为&#xff1a;段区块 硬盘都是长方形的&#xff0c;打了一个封装&#xff0c;里面是一个圆圈…