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

[Qt]系统相关-网络编程-TCP、UDP、HTTP协议

目录

前言

一、UDP网络编程

1.Qt项目文件

2.UDP类

QUdpSocket

QNetworkDatagram

3.UDP回显服务器案例

细节

服务器设计

客户端设计

二、TCP网络编程

1.TCP类

QTcpServer

QTcpSocket

2.TCP回显服务器案例

细节

服务器设计

客户端设计

三、HTTP客户端

1.HTTP客户端类 

QNetworkAccessManager

QNetworkRequest

QNetworkReply

2.HTTP客户端案例


前言

        我们之前学习的系统相关的内容,在不同的系统下的理论和实现可能都不太一样,但是对于计算机网络模块来说,因为网络提供了不同主机之间的信息通信,那么如何想让两个主机进行通信,那么他们的通信模块,也就是计算机模块的实现也就必须是一样的才可以。所以说计算机网络模块的实现对于不同的系统也是一样的,最主要的区别就是在于语言层面上,对于网络编程的系统接口的封装。对于C++标准库中,一直是没有提供网络编程相关的API库。

        在整个网络协议栈来看,网络编程就是我们对于用户层的一种编写,但是我们想要传输数据的时候需要传输层协议的支持,但是传输层协议有两个,所以我们在应用层也需要采用一些接口去指定传输层协议。

一、UDP网络编程

1.Qt项目文件

        .pro文件是 Qt 项目文件。它是一个文本文件,包含了项目的各种信息和配置,用于指导qmake如何构建 Qt 项目。所以在Qt中进行网络编程之前,需要在项目当中的.pro文件中添加network模块来引入网络编程模块。在我们之前使用的所有控件都是包含在QtCore模块当中的,只不过默认生成.pro文件的时候就已经添加了。而且Qt来提供了很多其他的模块。

        Qt为什么要划分出这么多模块呢?因为Qt本身是一个非常大的框架,如果我们默认把所有Qt提高的功能模块全都一下引入项目当中,那么即使我们写一个简单的打印helloworld,那么生成的可执行程序也会 非常的大,可执行程序内部编译了许多用不到的内容。所以为了让生成的Qt项目更加的轻量化,那么就把不同的功能划分成了多个模块,我们需要使用的时候,就需要在.pro文件中引入包含了。

        而且为了让多模块的项目更加的轻量化,Qt也提高了模块的动态库和静态库的两种版本。 

2.UDP类

        Qt对于UDP的类有两个,一个是QUdpSocket表示udp通信套接字文件类,另一个是表示一个UDP数据报的类QNetworkDatagram类。

QUdpSocket
名称说明

bind(const QHostAddress&,  quint16)

绑定指定的端口号
receiveDatagram()返回一个UDP数据报对象
writeDatagram(const QNetworkDatagram&)发送一个UDP数据报
readyRead信号在收到数据并准备就绪后触发
  • 对于读取数据的操作,在C++语言层面的接口或者系统的底层原生接口默认都是阻塞方式的等待,当然也可以设置非阻塞,而Qt在处理读取数据操作的时候,并不是阻塞或者非阻塞等待的方式,而是采用信号槽机制,当有数据到来并就绪只会,就会发送readRead信号。
  • QHostAddress是一个用于表示IP地址的一个类,对于服务器来说设置为QHostAddress::Any即可,表示可以用于监听任何地址的连接,对于IPv4和IPv6都适用。
  • 对于bind函数可能会绑定失败,但是他会将失败的原因存放起来,可以通过errorString成员函数获取到失败信息。
QNetworkDatagram
名称说明
QNetworkDatagram(const QByteArray&, const HostAddress&, quint16)构造函数,通过QByteArray,目标ip和端口号构造一个UDP数据报
data()获取数据报内部持有的数据,返回一个QByteArray类型对象
senderAddress()获取数据报中包含的对端ip地址
senderPort()获取数据报中包含的对端端口号

3.UDP回显服务器案例

        只是一个使用网络接口的案例,因为一般来说服务器都不会带有图形化界面的。

细节
  • 在readyRead信号绑定槽函数和bind操作的顺序来说,要先绑定信号槽,后bind,因为一旦绑定ip和端口号之后,就可能会有通信数据到来了。那么在进行信号槽的绑定,就会来不及了,早到的数据就因为没有槽函数,所以不进行处理了。
  • 我们下面的服务器设计中带有了图形化界面,在配置文件.pro文件中也可以看到我们引入了gui模块,那么我们的云服务器默认是没有装配图形化界面的,所以是没有办法直接将我们下面写的服务器端代码放入到云服务器允许的。
  • 而对于我们现在写的Qt的udp客户端是可以直接连接linux服务器下的udp服务器的。所以说网络底层协议的实现都是一样的。udp都是一套逻辑。一般Qt都不会写服务器,大多数都是写客户端,然后用Qt客户端连接linux服务器。
服务器设计

widget.h文件

class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();QString porcess(const QString& request);public slots:void processRequest();private:Ui::Widget *ui;//引入Udp成员QUdpSocket* socket;
};

widget.cpp文件 

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>
#include <QNetworkDatagram>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建udp对象socket = new QUdpSocket(this);//设置窗口标题this->setWindowTitle("服务器");//连接信号槽connect(socket, &QUdpSocket::readyRead, this, &Widget::processRequest);//绑定端口号bool retbind = socket->bind(QHostAddress::Any, 8082);if(retbind == false){QMessageBox::critical(this, "服务器启动出错", socket->errorString());return;}}Widget::~Widget()
{delete ui;
}//但是我们这里是回显,所以没有什么处理过程
QString Widget::porcess(const QString &request)
{return request;
}void Widget::processRequest()
{//获取请求信息const QNetworkDatagram& udp_request =  socket->receiveDatagram();//转化为字符串类型QString data_request = udp_request.data();//处理请求const QString& data = porcess(data_request);//构建相应数据报QNetworkDatagram response(data.toUtf8(), udp_request.senderAddress(), udp_request.senderPort());//发送回客户端socket->writeDatagram(response);//把客户端发的信息显示到listWidget控件上QString log = "[" + udp_request.senderAddress().toString() + ":" + QString::number(udp_request.senderPort())+ "]" + "message:" + data_request;ui->listWidget->addItem(log);
}
客户端设计

widget.h文件

class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pushButton_clicked();private:Ui::Widget *ui;//引入udp对象QUdpSocket* socket;
};

widget.cpp文件

#include "widget.h"
#include "ui_widget.h"
#include <QNetworkDatagram>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//设置窗口名称this->setWindowTitle("客户端");//创建udp对象socket = new QUdpSocket(this);//连接信号槽connect(socket, &QUdpSocket::readyRead, this, [=](){//获取数据报const QNetworkDatagram udp_response = socket->receiveDatagram();//读取数据const QString& data = udp_response.data();//写入对话框中ui->listWidget->addItem("服务器:" + data);});
}Widget::~Widget()
{delete ui;
}
//发送按钮
void Widget::on_pushButton_clicked()
{//获取输入框的内容const QString& text = ui->lineEdit->text();//构建请求数据报const QString ip = "127.0.0.1";const quint16 port = 8082;QNetworkDatagram data_request(text.toUtf8(), QHostAddress(ip), port);//发送数据socket->writeDatagram(data_request);//更新对话框中的内容ui->listWidget->addItem("客户端:" + text);//情况输入框ui->lineEdit->clear();
}

二、TCP网络编程

1.TCP类

        Qt对于TCP的类提供两个,第一个是QTcpServer用于监听端口,实现获取客户端连接的操作,相当于是listensocket以及对于bind、listen以及accept接口函数的一个封装。第二个是用于客户端和服务器之间数据交互的类QTcpSocket类。

QTcpServer
名称说明
listen(const QHostAddress&, quint16 port)绑定ip和端口号,并开始监听,相当于bind和listen的结合
nextPendingConnection()从系统当中获取到一个已经建立好的tcp连接,返回一个QTcpSocket对象,通过这个对象是实现与客户端之间的通信
newConnection信号有新的客户端建立连接完毕之后触发的信号
QTcpSocket
名称说明
readAll()读取当前接收缓冲区中的所有数据,返回QByteArray对象
write(const QByteArray&)把输入写入到socket的发送缓冲区中
deleteLater()暂时把socket对象标记为无效,Qt会在下个事件循环中析构释放该对象、
peerAddress()获取对端ip地址
peerPort()获取对端端口号

connectToHost( const QString &hostName, quint16 port)

向服务器发起连接
readyRead信号有数据到来并准备就绪触发
disconnected信号连接断开的时候触发

2.TCP回显服务器案例

细节
  • 对于客户端向服务器发起连接的connectToHost函数返回值为void类型,但是我们还是要判断是否连接成功了,所以QTcpSocket类中提供了waitForConnected函数,该函数的作用是让当前线程处理等待状态,直到连接成功,或者连接反馈错误为止,又或者说超时。
服务器设计

widget.h文件

class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();public slots:void processConnection();private:Ui::Widget *ui;//引入Tcp对象QTcpServer* socket;
};

widget.cpp文件

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//设置窗口标题this->setWindowTitle("服务器");//tcp对象实例化socket = new QTcpServer(this);//绑定newConnection的信号槽函数connect(socket, &QTcpServer::newConnection, this, &Widget::processConnection);//进行bind和listen操作bool retlisten = socket->listen(QHostAddress::Any, 8082);if(retlisten == false){QMessageBox::critical(this, "服务器启动失败", socket->errorString());return;}
}Widget::~Widget()
{delete ui;
}//获取新连接的信号处理函数
void Widget::processConnection()
{//获取新连接QTcpSocket* client = socket->nextPendingConnection();//构建日志QString log = "[" + client->peerAddress().toString() + ":" + QString::number(client->peerPort()) + "] 新客户端上线";ui->listWidget->addItem(log);//通过信号槽触发接收消息connect(client, &QTcpSocket::readyRead, this, [=](){//读取消息QString message = client->readAll();//处理消息--此处没有处理,只是回显//写回到客户端client->write(message.toUtf8());//构建日志QString log = "[" + client->peerAddress().toString() + ":" + QString::number(client->peerPort()) + "] say: " + message;//写到界面ui->listWidget->addItem(log);});//处理断开连接的信号槽函数connect(client, &QTcpSocket::disconnected, this, [=](){//构建日志QString log = "[" + client->peerAddress().toString() + ":" + QString::number(client->peerPort()) + "] 客户端下线";//释放对象client->deleteLater();});
}
客户端设计

widget.h文件

class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_pushButton_clicked();private:Ui::Widget *ui;//构建tcp对象QTcpSocket* socket;
};

widget.cpp文件

#include "widget.h"
#include "ui_widget.h"
#include <QMessageBox>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//设置窗口标题this->setWindowTitle("客户端 ");//实例化tcp对象socket = new QTcpSocket(this);//向服务器发起连接socket->connectToHost("127.0.0.1", 8082);//确认是否连接成功if(!socket->waitForConnected()){QMessageBox::critical(this, "连接服务器出错", socket->errorString());return;}//绑定接收到消息的信号槽函数connect(socket, &QTcpSocket::readyRead, this, [=](){//获取接收到的内容QString message = socket->readAll();//将内容打印到对话框中QString log = "服务器: " + message;ui->listWidget->addItem(log);});
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{//获取输入框的内容QString message = ui->lineEdit->text();//将内容发送给服务器socket->write(message.toUtf8());//将内容打印到对话框中ui->listWidget->addItem("客户端: " + message);//情况输入框ui->lineEdit->clear();
}

三、HTTP客户端

1.HTTP客户端类 

        Qt中为HTTP协议的客户端主要提供了三个类,一个是QNetworkAccessManager类,该类提供了HTTP有关的核心操作。第二个类是QNetworkRequest类表示一个不含body的HTTP请求。第三个类就是QNetworkReply类,表示一个HTTP的响应。

        上述也说了真正的服务器一定也不会使用Qt就实现,所以Qt就没有提供服务端相关的HTTP类。

QNetworkAccessManager
方法说明
get(const QNetworkRequest&)发起一个HTTP GET请求,返回一个QNetworkReply对象
post(const QNetworkRequest&, const QByteArray&)发起一个HTTP POST请求,也返回一个QNetworkReply对象
QNetworkRequest

        一个HTTP协议的完整报文应该是包括报头和有效载荷的,而这个类只是实现了一个报头,对于有效载荷该类不进行实现,而且对于请求报文来说一般都不会带有一些实质性的内容,只会传递一些kv形式的参数内容,通过post方法来传递,所以post方法也为我们提供了传递kv的参数。

方法说明
QNetworkRequest(const QUrl&)通过Url构造一个HTTP请求
setHeader(QNetworkRequest::knownHeaders header, const QVariant& value)设置请求头部字段

        对于报头的请求行字段,Qt也进行了一定的封装,方便我们去设置请求行,Qt中采用的是枚举类型将常用的请求行字段进行一一列举出来,QNetworkRequest::knownHeaders就是该枚举对象。 

        对于QVariant类对象表示一个类型可变的值。

QNetworkReply
方法说明
error()获取出错状态
errorString()获取出错原因的字符串描述
readAll()获取响应的body字段
header(QNetworkRequest::knownHeaders header)获取响应头部字段
finished信号当客户端收到一个完整的响应报文只会触发

2.HTTP客户端案例

细节

  • 如何想要显示出来元素的HTML报文,那么就不可以使用QTextEdit控件,因为他会对HTML代码进行渲染,显示出来的就不是原始的HTML报文了,所以需要使用QPlainTextEidt控件。
  • 对于get、post等系列函数只是负责发送请求,不负责请求的等待,所以说他返回的响应对象是一个没有实际内容的对象,那什么时候才收到响应呢?依靠的是finished信号,通过信号槽机制去处理finished信号,也就相当于处理响应了。
#include "widget.h"
#include "ui_widget.h"
#include <QNetworkReply>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//实例化manager = new QNetworkAccessManager(this);
}Widget::~Widget()
{delete ui;
}void Widget::on_pushButton_clicked()
{//获取到输入框中的url,并构建一个url对象QUrl url(ui->lineEdit->text());//构造一个http请求对象QNetworkRequest request(url);//发送get请求,返回一个响应QNetworkReply* response = manager->get(request);//信号槽connect(response, &QNetworkReply::finished, this, [=](){//正确响应了if(response->error() == QNetworkReply::NoError){QString html_data = response->readAll();ui->plainTextEdit->setPlainText(html_data);}else{ui->plainTextEdit->setPlainText(response->errorString());}//释放response对象response->deleteLater();});
}

相关文章:

[Qt]系统相关-网络编程-TCP、UDP、HTTP协议

目录 前言 一、UDP网络编程 1.Qt项目文件 2.UDP类 QUdpSocket QNetworkDatagram 3.UDP回显服务器案例 细节 服务器设计 客户端设计 二、TCP网络编程 1.TCP类 QTcpServer QTcpSocket 2.TCP回显服务器案例 细节 服务器设计 客户端设计 三、HTTP客户端 1.HTTP…...

docker 安装 nginx 详解

在平常的开发工作中&#xff0c;我们经常会用到 nginx&#xff0c;那么在 docker 中 如何安装 nginx呢&#xff1f;又有哪些需要注意的事项呢&#xff1f;简单来说&#xff0c;第一步&#xff1a;拉取 nginx 镜像&#xff1b;第二步&#xff1a;创建 挂载目录并设置 nginx.conf…...

2025年大模型气象预测架构与商业化影响

随着人工智能技术,尤其是大模型(如深度学习、大规模神经网络)的飞速发展,气象预测的传统方法正在经历深刻变革。2025年,气象预测将借助大模型技术进入一个新的阶段。本文将从架构角度详细探讨2025年大模型在气象预测中的应用,并分析其对商业化的潜在影响。 一、2025年大模…...

基于51单片机和ESP8266(01S)、八位数码管、独立按键的WiFi定时器时钟

目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、延时函数2、定时器03、串口4、数码管扫描5、独立按键扫描 四、主函数总结 系列文章目录 前言 有三个版本&#xff1a; ①普中开发板版本1&#xff1a;28800bps11.0592MHz&#xff0c;12T ②普中开发板版本2&am…...

Androidstudio 中,project下的.gitignore和module下的.gitignore有什么区别,生效优先级是什么

在 Android Studio 项目中&#xff0c;project 根目录下的 .gitignore 文件和 module 目录下的 .gitignore 文件作用和生效优先级是不同的&#xff0c;理解它们之间的区别非常重要&#xff0c;可以避免不必要的提交和冲突。 1. project 根目录下的 .gitignore&#xff1a; 作…...

python学习笔记3-字符串常用的方法

一、判断&#xff08;9个&#xff09;&#xff1a; 二、查找和替换&#xff08;8个&#xff09; 三、⼤⼩写转换&#xff08;5个&#xff09; 四、⽂本对⻬&#xff08;3个&#xff09; 五、去除空⽩字符&#xff08;3个&#xff09; 六、拆分和连接 &#xff08;6个&#xff0…...

提示词工程(Prompt Engineering)

1. Prompt 是什么&#xff1f; Prompt&#xff1a;提示词&#xff0c;是描述 AI 需要执行的任务的自然语言文本。 如上图所示&#xff0c;Prompt就是用户的提问。其实我们大家都用过Prompt&#xff0c;比如我们使用的ChatGPT、文心一言、豆包等AI产品时的提问就是Prompt&…...

后端开发Web

Maven Maven是apache旗下的一个开源项目&#xff0c;是一款用于管理和构建java项目的工具 Maven的作用 依赖管理 方便快捷的管理项目依赖的资源&#xff08;jar包&#xff09;&#xff0c;避免版本冲突问题 统一项目结构 提供标准、统一的项目结构 项目构建 标准跨平台(…...

set和map(二)详解

文章目录 mapoperator[ ]的底层operator[ ]使用的实例 multimapequal_range 两道题目题目解析算法原理代码题目解析算法原理代码 map map和set大部分都相似&#xff0c;只有insert插入键值对不同&#xff0c;insert要插入pair,pair中有key和value。erase和find只与key有关&…...

第4章:Python TDD消除重复与降低依赖实践

写在前面 这本书是我们老板推荐过的&#xff0c;我在《价值心法》的推荐书单里也看到了它。用了一段时间 Cursor 软件后&#xff0c;我突然思考&#xff0c;对于测试开发工程师来说&#xff0c;什么才更有价值呢&#xff1f;如何让 AI 工具更好地辅助自己写代码&#xff0c;或许…...

【语言处理和机器学习】概述篇(基础小白入门篇)

前言 自学笔记&#xff0c;分享给语言学/语言教育学方向的&#xff0c;但对语言数据处理感兴趣但是尚未入门&#xff0c;却需要在论文中用到的小伙伴&#xff0c;欢迎大佬们补充或绕道。ps&#xff1a;本文不涉及公式讲解&#xff08;文科生小白友好体质&#xff09;&#xff…...

vue3+uniapp开发鸿蒙初体验

去年7月20号&#xff0c;uniapp官网就已经开始支持鸿蒙应用开发了&#xff0c;话不多说&#xff0c;按照现有规则进行配置实现一下鸿蒙开发效果&#xff1b; 本文基于macOS Monterey 版本 12.6.5实现 开发鸿蒙的前置准备 这里就直接说我的版本&#xff1a; DevEco Studio 5.…...

Android四种方式刷新View

Android四种方式刷新View 1.前言&#xff1a; 最近在切换主题时有个TextView是Gone的状态&#xff0c;切换主题后内容没有显示&#xff0c;于是排查代码&#xff0c;刚开始以为是textView没有设置内容&#xff0c;但是打印日志和排查发现有setText. 2.View.VISIBLE与View.GO…...

【数学建模美赛速成系列】O奖论文绘图复现代码

文章目录 引言折线图 带误差棒得折线图单个带误差棒得折线图立体饼图完整复现代码 引言 美赛的绘图是非常重要得&#xff0c;这篇文章给大家分享我自己复现2024年美赛O奖优秀论文得代码&#xff0c;基于Matalab来实现&#xff0c;可以直接运行出图。 折线图 % MATLAB 官方整理…...

【27】Word:徐雅雯-艺术史文章❗

目录 题目​ NO1.2 NO3 NO4 NO5 NO6.7 NO8.9 NO10.11 注意&#xff1a;修改样式的字体颜色/字号&#xff0c;若中英文一致&#xff0c;选择所有脚本。格式相似的文本→检查多选/漏选格式刷F4重复上一步操作请❗每一步检查和保存 题目 NO1.2 F12另存为布局→行号布局…...

web端ActiveMq测试工具

如何用vue3创建简单的web端ActiveMq测试工具&#xff1f; 1、复用vue3模板框架 创建main.js,引入APP文件&#xff0c;createApp创建文件&#xff0c;并加载element插件&#xff0c;然后挂载dom节点 2、配置vue.config.js脚本配置 mport { defineConfig } from "vite&qu…...

2025年最新深度学习环境搭建:Win11+ cuDNN + CUDA + Pytorch +深度学习环境配置保姆级教程

本文目录 一、查看驱动版本1.1 查看显卡驱动1.2 显卡驱动和CUDA对应版本1.3 Pytorch和Python对应的版本1.4 Pytorch和CUDA对应的版本 二、安装CUDA三、安装cuDANN四、安装pytorch五、验证是否安装成功 一、查看驱动版本 1.1 查看显卡驱动 输入命令nvidia-smi可以查看对应的驱…...

FPGA中场战事

2023年10月3日,英特尔宣布由桑德拉里维拉(Sandra Rivera)担任“分拆”后独立运营的可编程事业部首席执行官。 从数据中心和人工智能(DCAI)部门总经理,转身为执掌该业务的CEO,对她取得像AMD掌门人苏姿丰博士类似的成功,无疑抱以厚望。 十年前,英特尔花费167亿美元真金白银…...

[Computer Vision]实验二:图像特征点提取

目录 一、实验内容 二、实验过程及结果 2.1 Harris角点检测 2.2 SIFT算法 三、实验小结 一、实验内容 采用Harris与SIFT分别提取特征点及对应的描述子&#xff0c;对比两者的区别&#xff08;特征点数量、分布、描述子维度、图像变化对二者的影响等&#xff09;利用特征匹…...

TCP状态转移图详解

状态 描述 LISTEN represents waiting for a connection request from any remote TCP and port. SYN-SENT represents waiting for a matching connection request after having sent a connection request. SYN-RECEIVED represents waiting for a confirming connect…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...