QT学习之旅 - network连接

news2024/9/27 21:20:28

文章目录

      • 网络知识点
        • IP地址
          • IPv4和IPv6
        • 端口号(协议端口)
          • 端口分类
          • UDP端口和TCP端口
      • network
        • pro文件
        • .h文件
        • .cpp文件
      • UDP连接
        • 绑定端口
        • 绑定成功后等待对方进行连接
        • 点击发送
        • 源码
        • 扩展: nodejs-udp服务端(用于跟QT程序进行通信)
        • 现象

网络知识点

IP地址

192.168.127.170(√)
192.168.330.170(×)

IP地址的范围在0~255

IPv4和IPv6

IPv4:32位(4个字节)
IPv6: 128位(16个字节)。新技术是漫游IP(就是多个局域网进行切换的时候,保持同一个IP地址不变),IPv6解决了IPv4面临枯竭的问题
v4和v6都是IP的版本的意思

端口号(协议端口)

16位(2个字节 short 1~65535)

端口分类
  • 通用端口: 1~1023(一般由系统来维护)
  • 注册端口: 1024~49151(应用,开发者来申请,建议使用5000以上端口号)
  • 临时端口: 49152~65535(通用和注册端口号都是给服务端的,这个临时端口号是给客户端的)
UDP端口和TCP端口

network

pro文件

QT       += network

我写在了``中

.h文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <timeclock.h>
#include <QtNetwork>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    QUrl url;
    QNetworkRequest req;
    QNetworkReply *reply;
    QNetworkAccessManager *manager;
private:
    Ui::MainWindow *ui;
    void startRequest(const QUrl &requestedUrl);
    void replyFinished();
};

#endif // MAINWINDOW_H

.cpp文件

void MainWindow::startRequest(const QUrl &requestedUrl){
    url = requestedUrl;
    manager = new QNetworkAccessManager(this);
    req.setUrl(url);
    req.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
    req.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36");
    reply = manager->get(req);
    connect(reply,&QNetworkReply::finished,this,&MainWindow::replyFinished);
}

void MainWindow::replyFinished(){

    // <1>判断有没有错误
    if (reply->error()){
        qDebug()<<reply->errorString();
        reply->deleteLater();
        return;
    }

    // <2>检测状态码
    int statusCode  = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    qDebug() << "statusCode:" << statusCode;

    // <3>判断是否需要重定向
    if (statusCode >= 200 && statusCode <300){
        // ok

        // 准备读数据
        QTextCodec *codec = QTextCodec::codecForName("utf8");
        QString all = codec->toUnicode(reply->readAll());
        qDebug() << all;


        // 保存HTTP响应内容
        // 组装保存的文件名 文件名格式: 路径/年_月_日 小时_分_秒 httpfile.html
        QDateTime current_date_time =QDateTime::currentDateTime();
        QString current_date =current_date_time.toString("yyyy_MM_dd hh_mm_ss");
        QString filePath = "D:/Qt/QTtest/qt4/myHTTP/doc";
        QString fileName = filePath + '/' + current_date + " httpfile" + ".html";

        QFile file(fileName);
        if (!file.open(QIODevice::ReadWrite | QIODevice::Text)){
            qDebug() << "file open error!";
            return ;
        }
        QTextStream out(&file);
        out.setCodec("UTF-8");
        out<<all << endl;
        file.close();


        // 数据读取完成之后,清除reply
        reply->deleteLater();
        reply = nullptr;

    } else if (statusCode >=300 && statusCode <400){
        // redirect

        // 获取重定向信息
        const QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
        // 检测是否需要重定向,如果不需要则读数据
        if (!redirectionTarget.isNull()) {
            const QUrl redirectedUrl = url.resolved(redirectionTarget.toUrl());

            reply->deleteLater();
            reply = nullptr;

            startRequest(redirectedUrl);
            qDebug()<< "http redirect to " << redirectedUrl.toString();
            return;
        }


    }

}

设置连接的URL

startRequest(QUrl(link));

UDP连接

在这里插入图片描述

绑定端口

udpSocket = new QUdpSocket(this);

/*
bind:绑定端口
QHostAddress::Any : 本机下所有的端口
udpSocket->bind(address,port);
*/
udpSocket->bind(QHostAddress::Any,9000);

绑定成功后等待对方进行连接

connect(udpSocket,&QUdpSocket::readyRead,this,&MainWindow::dealMsg);

在这里插入图片描述

void MainWindow::dealMsg(){
    //接收信息
    char buf[1024] = {0};
    QHostAddress ip;
    quint16 port;
    //readDatagram(数据缓存地址,缓存的数据大小,对方ip,对方端口)
    quint16 len = udpSocket->readDatagram(buf,sizeof(buf),&ip,&port);
    if(len > 0){
        //说明有接收,小于0是出错
        //显示
        QString str = QString("[%1:%2] %3")
                .arg(ip.toString())
                .arg(port)
                .arg(buf);

        ui->textEdit->append(str);
    }
}

点击发送

void MainWindow::on_buttonSend_clicked(){
  if(ui->lineEditIP == nullptr|| ui->lineEditPort == nullptr){
    return;
  }
  QString ip = ui->lineEditIP->text();
  quint16 port = ui->lineEditPort->text().toInt();
  //读取编辑区内容
  if(ui->textEditWrite == nullptr){
      return;
  }
  QString str = ui->textEditWrite->toPlainText();
  //写入套接字
  udpSocket->writeDatagram(str.toUtf8(),QHostAddress(ip),port);
  qDebug() << "send ip:" << ip;
  qDebug() << "send port:" << port;

}

源码

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{

    ui->setupUi(this);
    ui->textEdit->setReadOnly(true);//设置为只读
    
    setWindowTitle("端口号:9000");
    udpSocket = new QUdpSocket(this);

    /*
    bind:绑定端口
    QHostAddress::Any : 本机下所有的端口
    udpSocket->bind(address,port);
    */
    udpSocket->bind(QHostAddress::Any,9000);

    connect(udpSocket,&QUdpSocket::readyRead,this,&MainWindow::dealMsg);
    connect(ui->send,&QPushButton::clicked,this,&MainWindow::on_buttonSend_clicked);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::dealMsg(){
    //接收信息
    char buf[1024] = {0};
    QHostAddress ip;
    quint16 port;
    //readDatagram(数据缓存地址,缓存的数据大小,对方ip,对方端口)
    quint16 len = udpSocket->readDatagram(buf,sizeof(buf),&ip,&port);
    if(len > 0){
        //说明有接收,小于0是出错
        //显示
        QString str = QString("[%1:%2] %3")
                .arg(ip.toString())
                .arg(port)
                .arg(buf);

        qDebug() << "ip:" << ip;
        qDebug() << "port:" << port;

        ui->textEdit->append(str);
    }
}

void MainWindow::on_buttonSend_clicked(){
  if(ui->lineEditIP == nullptr|| ui->lineEditPort == nullptr){
    return;
  }
  QString ip = ui->lineEditIP->text();
  quint16 port = ui->lineEditPort->text().toInt();
  //读取编辑区内容
  if(ui->textEditWrite == nullptr){
      return;
  }
  QString str = ui->textEditWrite->toPlainText();
  //写入套接字
  udpSocket->writeDatagram(str.toUtf8(),QHostAddress(ip),port);
  qDebug() << "send ip:" << ip;
  qDebug() << "send port:" << port;

}

void MainWindow::on_buttonClose_clicked(){

}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QUdpSocket>
#include <QHostAddress>
#include <QLabel>
#include <QPushButton>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    QUdpSocket *udpSocket;
    void on_buttonSend_clicked();
    void on_buttonClose_clicked();
private slots:
    void dealMsg();
};
#endif // MAINWINDOW_H

在这里插入图片描述

扩展: nodejs-udp服务端(用于跟QT程序进行通信)

npm i express
//服务端
const dgram = require('dgram');
//创建udp server
let udp_server = dgram.createSocket('udp4');
udp_server.bind(5678);//绑定端口

//监听端口
udp_server.on('listening',function(){
    console.log('udp server linstening 5678.');
})

//接收消息
udp_server.on('message', function (msg, rinfo) {
    strmsg = msg.toString();
    udp_server.send(strmsg, 0, strmsg.length, rinfo.port, rinfo.address); //将接收到的消息返回给客户端
    console.log(`udp server received data: ${strmsg} from ${rinfo.address}:${rinfo.port}`)
})
//错误处理
udp_server.on('error', function (err) {
    console.log('some error on udp server.')
    udp_server.close();
})

//客户端
/* var dgram = require('dgram');
var udp_client = dgram.createSocket('udp4'); 

udp_client.on('close',function(){
    console.log('udp client closed.')
})

//错误处理
udp_client.on('error', function () {
    console.log('some error on udp client.')
})

// 接收消息
udp_client.on('message', function (msg,rinfo) {
    console.log(`receive message from ${rinfo.address}:${rinfo.port}:${msg}`);
})

//定时向服务器发送消息
setInterval(function(){
    var SendBuff = 'hello 123.';
    var SendLen = SendBuff.length;
    udp_client.send(SendBuff, 0, SendLen, 5678, '172.30.20.10'); 
},3000); */
npm run start

现象

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

结构化GPT用例,在CSDN私密社区中死磕@ada 探索SpringBoot

在CSDN私密社区中死磕ada 探索SpringBoot Q: Spring的核心概念是哪些&#xff1f;Q: Spring MVC的核心概念是哪些&#xff1f;Q: SpringBoot的核心概念有哪些&#xff1f;Q: 介绍下SpringBoot AutoConfiguration的机制。Q: SpringBootConfiguration 和 Configuration 的区别是&…

使用esp32+micropython+microdot搭建web(http+websocket)服务器(超详细)第二部分

使用esp32micropythonmicrodot搭建web(httpwebsocket)服务器&#xff08;超详细&#xff09;第二部分 microdot文档速查 什么是Microdot?Microdot是一个可以在micropython中搭建物联网web服务器的框架micropyton文档api速查 Quick reference for the ESP32 实现http服务器 …

基于cycle of curves的Nova证明系统

1. 引言 主要见斯坦福大学Wilson Nguyen、Dan Boneh和微软研究中心Srinath Setty 2023年论文《Revisiting the Nova Proof System on a Cycle of Curves》。 前序博客有&#xff1a; Nova: Recursive Zero-Knowledge Arguments from Folding Schemes学习笔记 在2021年Nova …

Java线程的六种状态(付代码解释)

目录 一.新建状态 (New) 解释 代码 运行结果 ​编辑 二.运行状态(Runnable) 解释 代码 运行结果 三.等待状态&#xff08;Waiting&#xff09; 解释 代码 运行结果 四.阻塞状态&#xff08;Blocked&#xff09; 解释 代码 运行结果 五.计时等待状态&#xff08;…

PCB设计系列分享-开关稳压器接地处理

目录 概要 整体架构流程 技术名词解释 1.DCDC&#xff1a; 2.PGND: 3.AGND: 技术细节 1.认识1 2.认识2 3.综合 小结 概要 提示&#xff1a;这里可以添加技术概要 如何使用带有模拟接地层(AGND)和功率接地层&#xff08;PGND)的开关稳压器? 这是许多开发人员在设计…

启用Windows应急重启功能

博主最近发现了Windows隐藏功能——应急重启&#xff0c;并且这个功能可以追溯到Windows Vista!但是因为大家习惯长按电源键关机所以就鲜为人知。今天博主叫你如何使用应急重启功能。 因为使用功能都无法截图&#xff0c;所以就不展示图片了。 第一步&#xff0c;按住CtrlAltD…

什么是元宇宙?元宇宙由哪些关键技术、设备构成?

元宇宙近几年来火爆起来,各个行业争先恐后加入。从目前来看,元宇宙初步体现在游戏娱乐行业、社交、消费、数字孪生等方面。元宇宙近两年开始在各个行业快速崛起,但各个行业并没有一个清晰的发展方向,那么什么是元宇宙? 元宇宙到底由哪些技术和设备组成&#xff1f;查询了很多资…

用于SOLIDWORKS装配体的X光机——SOLIDWORKS装配体直观工具

​ SOLIDWORKS报告和故障排除的瑞士军刀 如何快速的根据条件会装配体中的零部件进行分类&#xff1f; 如何快速找到装配体中的某些特定零件&#xff1f; 如何快速在图形区域中突出显示出特定的零部件&#xff1f; 如果你用过“SOLIDWORKS装配体直观工具”的话&#xff0c;…

JMeter之常见逻辑控制器实践

ForEach Controller(循环控制器) 组件使用说明 选项说明&#xff1a; ①需要循环遍历名称&#xff08;name&#xff09;&#xff1b; ②循环变量的下标起点(name_0)&#xff1b; ③循环变量的下标终点(name_4)&#xff1b; ④引用变量名称定义&#xff1b; ⑤在变量后加_&…

jsvmp xs逆向学习

内容仅供参考学习 欢迎朋友们V一起交流&#xff1a; zcxl7_7 首先直接搜索关键词 找到encrypt位置 接下来就是分析encrypt过程&#xff0c;详情请看专栏中的文章

leetcode 2448. Minimum Cost to Make Array Equal(使数组相等的最小成本)

数组nums的元素每次可进行下面的操作&#xff1a; 每个元素1 或者 -1。 操作一次的cost是cost[i]. 问把nums的元素全部变为相等的元素需要的最小的cost. 思路&#xff1a; nums的元素全部变为相等的元素&#xff0c;这个相等的元素是多少&#xff0c;现在不知道。 一旦知道了…

Jmeter查看结果树之查看响应的13种方法

目录 前言&#xff1a; 1、Text 2、RegExpTester 3、BoundaryExtractorTester 4、CSSSelectorTester 5、XpathTester 6、JSONPathTester 7、HTML 8、HTMLSourceFormatted 9、HTML&#xff08;downloadresources&#xff09; 10、Document 11、JSON 12、XML 13、B…

RPA×IDP×AIGC,实在智能打造全新“超进化”文档审阅超自动化解决方案

企业商业活动频繁&#xff0c;每日都有大量文档被创建、书写、传递&#xff0c;需要人工审阅核查&#xff0c;以确保其准确性和合法性。这是对企业文档管理的一个巨大挑战&#xff0c;尤其对于金融机构、审计机构等文本相关岗位的工作人员来说更是如此。传统的文档审核通常需要…

集合和泛型的详细讲解

集合 1&#xff09;可以动态保存任意多个对象&#xff0c;使用比较方便&#xff01; 2&#xff09;提供了一系列方便的操作对象的方法&#xff1a;add、remove、set、get等3&#xff09;使用集合添加&#xff0c;删除新元素的示意代码&#xff0d;简洁了 集合的框架体系 …

实时检测Aruco标签坐标opencv-python之添加卡尔曼滤波

在实时检测Aruco标签坐标用于定位的时候发现&#xff0c;追踪效果不是很好&#xff0c;于是在检测过程中添加了卡尔曼滤波&#xff0c;在aruco检测算法检测不到aruco标签的时候&#xff0c;调用卡尔曼滤波算法&#xff08;KalmanFilter&#xff09;&#xff0c;补偿丢失的定位的…

Rabbitmq学习

文章目录 前言RabbitMQ 1 同步调用和异步调用2 常见的MQ对比3 安装RabbitMQ4 RabbitMQ学习4.1 helloworld学习 5 Spring AMQP5.1 AMQP的入门案例(使用rabbittemplate进行消息发送和接受)5.2 RabbitMQ的workquene5.3 发布订阅模型(exchange(广播fanout 路由direct 话题topic))5.…

RK3588 修改USB/Sata/TF挂载点

文章目录 概要整体架构流程技术名词解释技术细节小结APP概要 rk3588 android12 平台的挂载点是:/storage/设备卷名(即uuid) 对上层开发不太友好,因此需要固定某个挂载点提供上层app调用。 修改后的路径效果如下: 整体架构流程 从概要图示中可知:对每个挂载点创建软连接来…

大牛分享,提高工程性能的7个简单技巧

软件性能和弹性&#xff08;恢复能力&#xff09;是用户体验的关键组成部分&#xff0c;但随着软件行业采用DevOps&#xff0c;它开始在性能和弹性方面出现不足。在软件完全失败之前&#xff0c;性能问题经常被忽略。 但是&#xff0c;我们都知道性能不会突然降低。随着软件通…

【二叉树part02】| 102.二叉树的层序遍历、226.翻转二叉树、101.对称二叉树

目录 ✿LeetCode102.二叉树的层序遍历❀ ✿LeetCode226.翻转二叉树❀ ✿LeetCode101.对称二叉树❀ ✿LeetCode102.二叉树的层序遍历❀ 链接&#xff1a;102.二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff…

Python入门(二十七)测试(二)

测试&#xff08;二&#xff09; 1.测试类2.各种断言方法3.一个要测试的类4.测试AnonymousSurvey类5.方法setUp() 1.测试类 前面我们编写了针对单个函数的测试&#xff0c;下面来编写针对类的测试。很多程序中都会用到类&#xff0c;因此证明我们的类能够正确工作大有裨益。如…