当前位置: 首页 > news >正文

Qt网络编程——QUdpSocket

文章目录

    • Qt网络编程
    • QUdpSocket
      • Udp回显服务器
      • Udp客户端

Qt网络编程

网络编程本质上是写应用层代码,需要传输层提供支持。

而传输层最核心的协议就是UDP和TCP,这两个协议有较大差别,所以Qt提供了两套API。

要是有Qt网络编程的API,需要现在.pro文件当中添加network模块。

之前的各种控件,各种内容都是包含在QtCore模块当中的(默认添加)

为什么要划分模块?

Qt本身十分庞大,包含了很多框架,如果把所有的Qt功能放到一起,即是写一个简单的hello world,此时生成的可执行程序也会非常庞大。

比如说,Qt会应用到嵌入式,嵌入式系统的配置并没有那么高,所以对空间的利用 > 对时间的利用

进行模块化处理,在默认情况下,其他额外的模块不参与编译,用的时候在.pro文件中引入对应的模块,才能把对应功能给编译加载进来。

网络编程是操作系统提供的API,

C++标准库里面还未提供网络编程的api封装

QUdpSocket

名称类型说明原生API
bind(const QHostAddress&, quint16)方法绑定指定端口bind
receiveDatagram()方法返回QNetWorkDatagram
读取UDP数据报
recvfrom
writeDatagram(const QNetworkDatagram&)方法发送UDP数据报sendto
readyRead信号收到数据并准备就绪后触发无(类似与IO多路复用机制)

QNetWorkDatagram表示有个UDP数据报

名称类型说明原生API
QNetworkDatagram(const QByteArray&, const QHostAddress&, quint16)构造函数通过QByteArray,目标IP地址目标端口号,构造一个UDP数据报
通常用于发送数据时
data()方法获取数据报内部持有的数据
返回QByteArray
senderAddress()方法获取数据报中包含的对端IP地址无,recvfrom包含此类功能
senderPort()方法获取数据报中包含的对端的端口号无,recvfrom包含此类功能

Udp回显服务器

一般服务器都没有图形化界面,此处为了更加直观看到,采用图形化界面方式

ui界面:

image-20240924212556093

.pro引入network模块

image-20240924213217801

widget.h

这里需要包含QUdpSocket头文件,包含之后可能还是会显示报错,将程序重新编译运行一下即可

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include<QUdpSocket>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;QUdpSocket* socket;void processRequest();QString process(const QString& request);
};
#endif // WIDGET_H

widget.cpp

构造对象的时候,参数可以是parent,也就是挂到对象树上(如果不写,之后手动delete即可)

image-20240925211236570

要线连接信号槽,再进行bind

一旦进行bind,就意味着请求可以收到了。

如果在连接信号槽之前bind,可能收到请求,而信号槽还没连接,此时请求就丢失了

#include "widget.h"
#include "ui_widget.h"
#include<QMessageBox>
#include<QNetworkDatagram>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建实例socket = new QUdpSocket(this);  //可以挂到对象树//设置窗口标题this->setWindowTitle("udp服务器");//连接信号槽connect(socket, &QUdpSocket::readyRead, this, &Widget::processRequest);//绑定端口号//any表示不管几个网卡,都可以绑定上去if(!socket->bind(QHostAddress::Any, 8080)){QMessageBox::critical(this, "bind error", socket->errorString());return;}
}Widget::~Widget()
{delete ui;
}void Widget::processRequest()
{//读取请求并解析const QNetworkDatagram& requestDatagram = socket->receiveDatagram();//data()返回QByteArray  QBtyeArray可以赋值给QStringQString request = requestDatagram.data();//根据请求计算(此时是回显服务器, 收到什么响应什么)const QString& response = process(request);//把响应写给客户端//取出字节数组 发送到的地址 发送到的端口 都包含在requestDatagramQNetworkDatagram responseDatagram(response.toUtf8(), requestDatagram.senderAddress(), requestDatagram.senderPort());socket->writeDatagram(responseDatagram);//交互的信息 显式到界面QString log = "[" + requestDatagram.senderAddress().toString() + ":" + QString::number(requestDatagram.senderPort()) +"] req:" + request + ", resp: " + response;ui->listWidget->addItem(log);
}QString Widget::process(const QString &request)
{return request;
}

Udp客户端

Qt Creator支持同时打开多个项目,但如果姓名中存在同名文件,就非常容易混淆

image-20240924215956667

客户端主动发起请求,界面设置一个输入框,一个发送按钮,一个显示服务器返回内容

image-20240924220714547

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include<QUdpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pushButton_clicked();void processResponse();
private:Ui::Widget *ui;QUdpSocket* socket;
};
#endif // WIDGET_H

widget.cpp

在Linux中,需要考虑一些阻塞问题,什么时候阻塞,什么时候解除阻塞。

而这里直接用信号槽机制,很方便。

#include "widget.h"
#include "ui_widget.h"
#include<QNetworkDatagram>
const QString SERVER_IP = "127.0.0.1";
const quint16 SERVER_PORT = 8080;Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);socket = new QUdpSocket(this);//修改窗口标题this->setWindowTitle("客户端");//通过信号槽处理返回的数据connect(socket, &QUdpSocket::readyRead, this, &Widget::processResponse);}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{//获取输入框内容const QString& text = ui->lineEdit->text();//构造udp请求数据包//需要的参数是字节数组,要转换一下 IP地址也要转换一下QNetworkDatagram requestDatagram(text.toUtf8(), QHostAddress(SERVER_IP), SERVER_PORT);//发送请求数据socket->writeDatagram(requestDatagram);//发送的请求添加到列表框ui->listWidget->addItem("client say# " + text);//输入框内容清空ui->lineEdit->setText("");
}void Widget::processResponse()
{//读取响应数据const QNetworkDatagram& responseDatagram = socket->receiveDatagram();QString response = responseDatagram.data();//响应到界面ui->listWidget->addItem("server say# " + response);
}

GIF 2024-9-25 21-31-21

相关文章:

  • [大语言模型-论文精读] MoRAG - 基于多部分融合的检索增强型人体动作生成
  • [C++][程序退出]详细讲解
  • C++【类和对象】(取地址运算符重载与实现Date类)
  • Jenkins提示Host key verification failed的解决办法
  • RabbitMQ 消息队列:生产者与消费者实现详解
  • how to remove the text shadow under app icon on Windows
  • Java 编码系列:反射详解与面试题解析
  • 更新系统提示“系统备份失败”
  • 工厂模式与建造者模式的区别
  • 【js】Node.js的fs的使用方法
  • Spring源码学习:SpringMVC(3)mvcannotation-driven标签解析【RequestMappingHandlerMapping生成】
  • 技术成神之路:设计模式(十六)代理模式
  • Python库matplotlib之五
  • 【RabbitMq源码阅读】分析RabbitMq发送消息源码
  • Robot Operating System——一组三维空间中的位姿(位置和方向)
  • 【Leetcode】104. 二叉树的最大深度
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • Bootstrap JS插件Alert源码分析
  • Docker入门(二) - Dockerfile
  • gf框架之分页模块(五) - 自定义分页
  • git 常用命令
  • LeetCode刷题——29. Divide Two Integers(Part 1靠自己)
  • Linux各目录及每个目录的详细介绍
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • Quartz初级教程
  • tab.js分享及浏览器兼容性问题汇总
  • use Google search engine
  • VuePress 静态网站生成
  • vue学习系列(二)vue-cli
  • 阿里云前端周刊 - 第 26 期
  • 从PHP迁移至Golang - 基础篇
  • 前端技术周刊 2019-02-11 Serverless
  • 前嗅ForeSpider教程:创建模板
  • 小程序测试方案初探
  • 赢得Docker挑战最佳实践
  • 智能合约Solidity教程-事件和日志(一)
  • 走向全栈之MongoDB的使用
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • 正则表达式-基础知识Review
  • # 利刃出鞘_Tomcat 核心原理解析(七)
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (C语言)共用体union的用法举例
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (TOJ2804)Even? Odd?
  • (笔试题)合法字符串
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (十三)MipMap
  • (详细文档!)javaswing图书管理系统+mysql数据库
  • (转)EOS中账户、钱包和密钥的关系
  • (转)我也是一只IT小小鸟