【史上最全面ESP32教程】http通信
文章目录
- 前言
- HTTP协议是什么?
- HTTP协议的特点
- HTTP协议的常见应用
- esp32 使用http通信
- 通信流程
- 基础使用
- HTTPClient 常用的函数
- 函数介绍:
- `void end(void);`
- `bool connected(void);`
- `void setReuse(bool reuse);`
- `void setUserAgent(const String& userAgent);`
- `void setAuthorization(const char * user, const char * password);`
- `int GET();`
- `String getString(void);`
- `int PATCH(uint8_t * payload, size_t size);`
- `int PATCH(String payload);`
- `int POST(uint8_t * payload, size_t size);`
- `int POST(String payload);`
- `int PUT(uint8_t * payload, size_t size);`
- `int PUT(String payload);`
- `int sendRequest(const char * type, String payload);`
- `void addHeader(const String& name, const String& value, bool first = false, bool replace = true);`
- `void collectHeaders(const char* headerKeys[], const size_t headerKeysCount);`
- `String header(const char* name);`
- `String header(size_t i);`
- `String headerName(size_t i);`
- `int headers();`
- `bool hasHeader(const char* name);`
- `int getSize(void);`
- `const String &getLocation(void);`
- `WiFiClient& getStream(void);`
- `WiFiClient* getStreamPtr(void);`
- `int writeToStream(Stream* stream);`
- `String getString(void);`
- `static String errorToString(int error);`
- `void setCookieJar(CookieJar* cookieJar);`
- `void resetCookieJar();`
- `void clearAllCookies();`
- 总结
前言
随着物联网(IoT)的快速发展,ESP32作为一款高性能、低功耗的Wi-Fi和蓝牙双模芯片,受到了广泛的关注和应用。在物联网设备中,HTTP协议是实现设备与服务器之间通信的常用协议。本文将介绍HTTP协议的基本概念及其常见应用场景。
HTTP协议是什么?
HTTP(HyperText Transfer Protocol,超文本传输协议)是一种用于传输超文本的应用层协议。它是万维网(WWW)的基础,定义了客户端(如浏览器)与服务器之间的通信规则。HTTP协议采用请求-响应模式,客户端发送请求,服务器返回响应。
HTTP协议的特点
- 无状态:每次请求都是独立的,服务器不会保留之前请求的状态。
- 灵活性:支持多种数据格式,如HTML、JSON、XML等。
- 简单性:易于实现和使用,广泛应用于Web开发。
HTTP协议的常见应用
- Web浏览:浏览器通过HTTP协议请求网页内容,服务器返回HTML页面。
- API通信:物联网设备通过HTTP协议与服务器进行数据交互,如上传传感器数据或获取控制指令。
- 文件传输:通过HTTP协议下载或上传文件,如软件更新或日志文件。
esp32 使用http通信
通信流程
- 连接网络
- 开始http通信
- 发送请求并获取响应
- 关闭连接
基础使用
我们需要使用HTTPClient类来进行通信
如果我们要开启一个http通信使用下面这个函数,参数为你要http通信的url:
bool begin(String url);
如果我们要GET一个内容,我们可以使用下面这个函数:
int GET();
他的返回值为状态码。
状态码有下面这些取值:
- 200 OK:请求成功。具体的含义取决于HTTP方法。例如,GET方法表示资源已被获取并在消息体中传输。
- 201 Created:请求成功,并且新的资源已经作为结果创建。这通常是在POST请求或某些PUT请求后发送的响应。
- 204 No Content:没有要发送的内容,但头部可能有用。用户代理可能会使用新的头部更新此资源的缓存头部。
- 301 Moved Permanently:请求的URL已永久移动到新位置,并且将来的引用应使用新的URL。
- 400 Bad Request:服务器无法理解请求的语法。
- 401 Unauthorized:请求需要用户验证。
- 403 Forbidden:服务器理解请求,但拒绝执行它。
- 404 Not Found:服务器找不到请求的资源。
- 500 Internal Server Error:服务器遇到错误,无法完成请求
我们可以通过下面这个函数来获取GET的返回值:
String getString(void);
我们可以使用下面这个函数来关闭http连接:
void end(void);
#include <WiFi.h>
#include <HTTPClient.h>const char* ssid = "......."; // WiFi网络名称
const char* password = "......."; // WiFi网络密码void setup() {Serial.begin(115200); // 初始化串口通信// 连接到WiFi网络WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(1000);Serial.println("Connecting to WiFi...");}Serial.println("Connected to WiFi");// 设置HTTPClient对象HTTPClient http;// 为GET请求设置目标URLString url = "http://example.com/api/data"; // 替换为你的目标URL// 发送GET请求http.begin(url);// 发送请求并获取响应int httpResponseCode = http.GET();if (httpResponseCode > 0) { // 如果收到响应Serial.print("HTTP Response code: ");Serial.println(httpResponseCode); // 打印响应代码String payload = http.getString(); // 获取响应内容Serial.println(payload); // 打印响应内容} else {Serial.print("Error code: ");Serial.println(httpResponseCode); // 打印错误代码}http.end(); // 关闭连接
}void loop() {// 程序主循环,此处不需要添加其他代码
}
HTTPClient 常用的函数
函数介绍:
void end(void);
- 函数原型:
void end(void); - 函数作用: 关闭HTTPClient对象,释放资源。
- 函数参数: 无。
- 返回值的作用: 无返回值。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); // 处理响应 http.end(); // 关闭HTTP连接
bool connected(void);
- 函数原型:
bool connected(void); - 函数作用: 检查HTTPClient对象是否已连接到服务器。
- 函数参数: 无。
- 返回值的作用: 返回
true表示连接成功,返回false表示未连接或连接已断开。 - 示例代码:
HTTPClient http; if (http.connected()) {// 执行请求操作 } else {// 重新连接或处理断开连接情况 }
void setReuse(bool reuse);
- 函数原型:
void setReuse(bool reuse); - 函数作用: 设置是否启用HTTP keep-alive功能,允许多次复用同一TCP连接。
- 函数参数:
reuse:布尔值,true表示启用keep-alive,false表示禁用。
- 返回值的作用: 无返回值。
- 示例代码:
HTTPClient http; http.setReuse(true); // 启用keep-alive
void setUserAgent(const String& userAgent);
- 函数原型:
void setUserAgent(const String& userAgent); - 函数作用: 设置HTTP请求的用户代理(User-Agent)标头。
- 函数参数:
userAgent:String类型,要设置的用户代理字符串。
- 返回值的作用: 无返回值。
- 示例代码:
HTTPClient http; http.setUserAgent("ESP32 Client");
void setAuthorization(const char * user, const char * password);
- 函数原型:
void setAuthorization(const char * user, const char * password); - 函数作用: 设置基本身份验证的用户名和密码。
- 函数参数:
user:用户名字符串。password:密码字符串。
- 返回值的作用: 无返回值。
- 示例代码:
HTTPClient http; http.setAuthorization("username", "password");
int GET();
- 函数原型:
int GET(); - 函数作用: 发送HTTP GET请求并接收响应。
- 函数参数: 无。
- 返回值的作用: 返回HTTP响应状态代码(例如200表示成功)。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); // 处理响应
String getString(void);
- 函数原型:
String getString(void); - 函数作用: 获取HTTP响应的正文内容。
- 函数参数: 无。
- 返回值的作用: 返回包含HTTP响应正文内容的String对象。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); if (httpResponseCode > 0) {String response = http.getString();Serial.println(response); }
int PATCH(uint8_t * payload, size_t size);
- 函数原型:
int PATCH(uint8_t * payload, size_t size); - 函数作用: 发送HTTP PATCH请求并附带数据。
- 函数参数:
payload:指向要发送数据的字节数组的指针。size:要发送数据的大小(字节数)。
- 返回值的作用: 返回HTTP响应状态代码。
- 示例代码:
HTTPClient http; uint8_t data[] = { 0x01, 0x02, 0x03 }; int httpResponseCode = http.PATCH(data, sizeof(data));
int PATCH(String payload);
- 函数原型:
int PATCH(String payload); - 函数作用: 发送HTTP PATCH请求并附带数据(字符串形式)。
- 函数参数:
payload:要发送的数据字符串。
- 返回值的作用: 返回HTTP响应状态代码。
- 示例代码:
HTTPClient http; String data = "key=value"; int httpResponseCode = http.PATCH(data);
int POST(uint8_t * payload, size_t size);
- 函数原型:
int POST(uint8_t * payload, size_t size); - 函数作用: 发送HTTP POST请求并附带数据。
- 函数参数:
payload:指向要发送数据的字节数组的指针。size:要发送数据的大小(字节数)。
- 返回值的作用: 返回HTTP响应状态代码。
- 示例代码:
HTTPClient http; uint8_t data[] = { 0x01, 0x02, 0x03 }; int httpResponseCode = http.POST(data, sizeof(data));
int POST(String payload);
- 函数原型:
int POST(String payload); - 函数作用: 发送HTTP POST请求并附带数据(字符串形式)。
- 函数参数:
payload:要发送的数据字符串。
- 返回值的作用: 返回HTTP响应状态代码。
- 示例代码:
HTTPClient http; String data = "key=value"; int httpResponseCode = http.POST(data);
int PUT(uint8_t * payload, size_t size);
- 函数原型:
int PUT(uint8_t * payload, size_t size); - 函数作用: 发送HTTP PUT请求并附带数据。
- 函数参数:
payload:指向要发送数据的字节数组的指针。size:要发送数据的大小(字节数)。
- 返回值的作用: 返回HTTP响应状态代码。
- 示例代码:
HTTPClient http; uint8_t data[] = { 0x01, 0x02, 0x03 }; int httpResponseCode = http.PUT(data, sizeof(data));
int PUT(String payload);
- 函数原型:
int PUT(String payload); - 函数作用: 发送HTTP PUT请求并附带数据(字符串形式)。
- 函数参数:
payload:要发送的数据字符串。
- 返回值的作用: 返回HTTP响应状态代码。
- 示例代码:
HTTPClient http; String data = "key=value"; int httpResponseCode = http.PUT(data);
int sendRequest(const char * type, String payload);
- 函数原型:
int sendRequest(const char * type, String payload); - 函数作用: 发送自定义类型的HTTP请求,并附带数据(字符串形式)。
- 函数参数:
type:HTTP请求类型,例如 “GET”, “POST”, “PUT” 等。payload:要发送的数据字符串。
- 返回值的作用: 返回HTTP响应状态代码。
- 示例代码:
HTTPClient http; int httpResponseCode = http.sendRequest("POST", "key=value");
void addHeader(const String& name, const String& value, bool first = false, bool replace = true);
- 函数原型:
void addHeader(const String& name, const String& value, bool first = false, bool replace = true); - 函数作用: 添加HTTP请求头。
- 函数参数:
name:头部字段的名称。value:头部字段的值。first:可选参数,默认为false。如果为true,则将新头部添加到头部列表的开头。replace:可选参数,默认为true。如果为true,则替换现有的同名头部;如果为false,则添加到现有同名头部后面。
- 返回值的作用: 无返回值。
- 示例代码:
HTTPClient http; http.addHeader("Content-Type", "application/json");
void collectHeaders(const char* headerKeys[], const size_t headerKeysCount);
- 函数原型:
void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); - 函数作用: 指定要收集的HTTP响应头。
- 函数参数:
headerKeys:指向包含要收集的头部字段名称的数组。headerKeysCount:数组中头部字段名称的数量。
- 返回值的作用: 无返回值。
- 示例代码:
const char* headersToCollect[] = { "Content-Length", "Content-Type" }; HTTPClient http; http.collectHeaders(headersToCollect, sizeof(headersToCollect) / sizeof(headersToCollect[0]));
String header(const char* name);
- 函数原型:
String header(const char* name); - 函数作用: 获取指定名称的HTTP响应头值。
- 函数参数:
name:要获取的头部字段名称。
- 返回值的作用: 返回包含头部字段值的String对象。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); String contentType = http.header("Content-Type");
String header(size_t i);
- 函数原型:
String header(size_t i); - 函数作用: 获取指定索引位置的HTTP响应头值。
- 函数参数:
i:要获取的头部字段的索引(从0开始)。
- 返回值的作用: 返回包含头部字段值的String对象。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); String firstHeader = http.header(0);
String headerName(size_t i);
- 函数原型:
String headerName(size_t i); - 函数作用: 获取指定索引位置的HTTP响应头名称。
- 函数参数:
i:要获取的头部字段的索引(从0开始)。
- 返回值的作用: 返回包含头部字段名称的String对象。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); String firstName = http.headerName(0);
int headers();
- 函数原型:
int headers(); - 函数作用: 获取HTTP响应中头部字段的数量。
- 函数参数: 无。
- 返回值的作用: 返回头部字段的数量。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); int numHeaders = http.headers();
bool hasHeader(const char* name);
- 函数原型:
bool hasHeader(const char* name); - 函数作用: 检查HTTP响应中是否存在指定名称的头部字段。
- 函数参数:
name:要检查
的头部字段名称。
- 返回值的作用: 如果存在指定名称的头部字段,则返回
true;否则返回false。 - 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); if (http.hasHeader("Content-Type")) {// 处理存在Content-Type头部的情况 }
int getSize(void);
- 函数原型:
int getSize(void); - 函数作用: 获取HTTP响应正文的大小(字节数)。
- 函数参数: 无。
- 返回值的作用: 返回HTTP响应正文的大小。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); int contentSize = http.getSize();
const String &getLocation(void);
- 函数原型:
const String &getLocation(void); - 函数作用: 获取HTTP响应中的
Location头部字段的值,用于处理重定向。 - 函数参数: 无。
- 返回值的作用: 返回包含
Location头部字段值的String对象的引用。 - 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); String redirectLocation = http.getLocation();
WiFiClient& getStream(void);
- 函数原型:
WiFiClient& getStream(void); - 函数作用: 获取底层的WiFiClient对象,用于直接访问底层网络连接。
- 函数参数: 无。
- 返回值的作用: 返回一个WiFiClient对象的引用。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); WiFiClient& stream = http.getStream();
WiFiClient* getStreamPtr(void);
- 函数原型:
WiFiClient* getStreamPtr(void); - 函数作用: 获取底层的WiFiClient对象指针,用于直接访问底层网络连接。
- 函数参数: 无。
- 返回值的作用: 返回一个指向WiFiClient对象的指针。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); WiFiClient* streamPtr = http.getStreamPtr();
int writeToStream(Stream* stream);
- 函数原型:
int writeToStream(Stream* stream); - 函数作用: 将HTTP响应内容写入给定的流(Stream)对象。
- 函数参数:
stream:指向目标流对象的指针。
- 返回值的作用: 返回写入流的字节数。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); WiFiClient client; int bytesWritten = http.writeToStream(&client);
String getString(void);
- 函数原型:
String getString(void); - 函数作用: 获取HTTP响应的正文内容。
- 函数参数: 无。
- 返回值的作用: 返回包含HTTP响应正文内容的String对象。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); String response = http.getString();
static String errorToString(int error);
- 函数原型:
static String errorToString(int error); - 函数作用: 将HTTPClient库中的错误代码转换为对应的错误消息字符串。
- 函数参数:
error:HTTPClient库中定义的错误代码。
- 返回值的作用: 返回表示错误消息的String对象。
- 示例代码:
HTTPClient http; http.begin("http://example.com/api/data"); int httpResponseCode = http.GET(); if (httpResponseCode < 0) {String errorMessage = HTTPClient::errorToString(httpResponseCode);Serial.println(errorMessage); }
void setCookieJar(CookieJar* cookieJar);
- 函数原型:
void setCookieJar(CookieJar* cookieJar); - 函数作用: 设置用于管理HTTP请求和响应中Cookie的CookieJar对象。
- 函数参数:
cookieJar:指向CookieJar对象的指针。
- 返回值的作用: 无返回值。
- 示例代码:
CookieJar cookieJar; HTTPClient http; http.setCookieJar(&cookieJar);
void resetCookieJar();
- 函数原型:
void resetCookieJar(); - 函数作用: 重置CookieJar,清除所有保存的Cookie。
- 函数参数: 无。
- 返回值的作用: 无返回值。
- 示例代码:
HTTPClient http; http.resetCookieJar();
void clearAllCookies();
- 函数原型:
void clearAllCookies(); - 函数作用: 清除所有保存的Cookie,无论它们是否过期。
- 函数参数: 无。
- 返回值的作用: 无返回值。
- 示例代码:
HTTPClient http; http.clearAllCookies();
总结
本文简要介绍了HTTP协议的基本概念及其在物联网设备中的常见应用。HTTP协议作为一种简单、灵活的通信协议,广泛应用于Web开发和物联网设备中。希望本文能帮助读者更好地理解HTTP协议及其在ESP32中的应用。
相关文章:
【史上最全面ESP32教程】http通信
文章目录 前言HTTP协议是什么?HTTP协议的特点HTTP协议的常见应用 esp32 使用http通信通信流程基础使用HTTPClient 常用的函数函数介绍:void end(void);bool connected(void);void setReuse(bool reuse);void setUserAgent(const String& userAgent);…...
*算法训练(leetcode)第二十七天 | 56. 合并区间、738. 单调递增的数字、968. 监控二叉树
刷题记录 56. 合并区间*738. 单调递增的数字*968. 监控二叉树 56. 合并区间 leetcode题目地址 排序后遇到有重合的区间选择最大的区间保存即可,结果集中保存的是离当前区间最近的区间,因此使用当前区间与结果集中的最后一个集合比较查看是否有重合&…...
OpenJudge 奇数求和
目录 描述思路样例输入样例输出CodeCC 总时间限制: 1000ms 内存限制: 65536kB 描述 计算非负整数 m 到 n(包括m 和 n )之间的所有奇数的和,其中,m 不大于 n,且n 不大于300。例如 m3, n12, 其和则为:357911…...
【排序 - 快速排序】
快速排序(Quick Sort)是一种高效的排序算法,它基于分治(Divide and Conquer)的策略。这种排序算法的核心思想是选择一个基准元素,将数组分割成两部分,使得左边的元素都小于等于基准元素…...
pytest使用报错(以及解决pytest所谓的“抑制print输出”)
1. 测试类的类名问题 #codingutf-8import pytestclass TestClass1:def setup(self) -> None:print(setup)def test_01(self) -> None:print(test_01111111111111111111111)def test_02(self) -> None:print(test_02)以上述代码为例,如果类名是Test开头&am…...
开源项目编译harbor arm架构的包 —— 筑梦之路
GitHub - amy5200/harbor-arm64 先做个记录,空了再验证...
[笔记] SKF Enveloping FAQ 用户指南
文档编号:Application Note CM3013 1.名词解释: 1.1cavitationWhat Is Cavitation? | Pumps & Systems 叶片在液体中扰动形成的超声波 1.2 stiff machinehttps://suspensionlist.com/the-pros-and-cons-of-stiff-vs-soft-suspension-systems/ …...
宪法学学习笔记(个人向) Part.3
宪法学学习笔记(个人向) Part 3 3. 国家基本制度 3.1 国家性质 3.1.1 国家性质概述 国家性质的概念 国家性质也称国体,或国家的阶级本质,是指各个阶级在国家中的地位(哪个阶层是统治阶层,哪个阶层是被统治阶层,哪个…...
联想拯救者Y7000 IRX9 笔记本接口功能介绍
适用机型:Legion Y7000 IRX9; 83JJ; USB(3.2 Gen 1)Type-接口摄像头开关组合音频插孔 多用于USB Type-C接口 以太网接口 多用途USB Type-C接口(支持USB Power Delivery)HDMI接口USB(3.2 Gen 1&…...
【ESP32】打造全网最强esp-idf基础教程——16.SmartConfig一键配网
SmartConfig一键配网 一、SmartConfig知识扫盲 在讲STA课程的时候,我们用的是代码里面固定的SSID和密码去连接热点,但实际应用中不可能这么弄,我们得有办法把家里的WiFi SSID和密码输入到设备里面去,对于带屏带输入设备还…...
MD5加密和注册页面的编写
MD5加密 1.导入包 npm install --save ts-md5 2.使用方式 import { Md5 } from ts-md5; //md5加密后的密码 const md5PwdMd5.hashStr("123456").toUpperCase(); 遇见的问题及用到的技术 注册页面 register.vue代码 <template><div class"wappe…...
【Android组件】封装加载弹框
📖封装加载弹框 ✅1. 构造LoadingDialog✅2. 调用LoadingDialog 效果: ✅1. 构造LoadingDialog 构造LoadingDialog类涉及到设计模式中的建造者模式,进行链式调用,注重的是构建的过程,设置需要的属性。 步骤一&#x…...
Spring源码二十:Bean实例化流程三
上一篇Spring源码十九:Bean实例化流程二中,我们主要讨论了单例Bean创建对象的主要方法getSingleton了解到了他的核心流程无非是:通过一个简单工厂的getObject方法来实例化bean,当然spring在实例化前后提供了扩展如:bef…...
前端导出文件时,后端代码出错如何将错误信息返回给前端展示
功能说明:前端导出excel时,后端出现异常,比如sql异常,或者创建excel时出现的异常,希望将这些异常信息返回给前端查看。 框架:vue3 axios Springboot 实现难度分析:前端导出excel,…...
解决Spring Boot应用中的内存优化问题
解决Spring Boot应用中的内存优化问题 大家好,我是微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿! 1. Spring Boot应用的内存管理 在开发和部署Spring Boot应用时,有效地管理内存是确保应用性能和稳…...
shark云原生-日志体系-filebeat高级配置(适用于生产)-更新中
文章目录 1. filebeat.inputs 静态日志收集器2. filebeat.autodiscover 自动发现2.1. autodiscover 和 inputs2.2. 如何配置生效2.3. Providers 提供者2.4. Providers kubernetes2.5. 配置 templates2.5.1. kubernetes 自动发现事件中的变量字段2.5.2 配置 templates 2.6. 基于…...
响应式设计的双璧:WebKit 支持 CSS Flexbox 和 Grid 布局深度解析
响应式设计的双璧:WebKit 支持 CSS Flexbox 和 Grid 布局深度解析 在现代网页设计中,响应式布局是实现跨设备兼容性的关键。CSS Flexbox 和 Grid 作为 CSS 布局的两大支柱,提供了强大的工具来构建灵活和复杂的用户界面。WebKit,作…...
Linux软件包管理
一、软件包管理 1.什么是软件包 一般在window系统的.exe是软件按转包 2.linux系统下的软件包安装方式 PRM 软件包安装 软件名称.rpmYUM 包管理工具 yum intall 软件名称 -y源码安装 下载源代码---编译---安装 很麻烦,稳定 3.二进制软件包 二进制 4.获取*.rpm…...
如何分辨AI生成的内容?AI生成内容检测工具对比实验
检测人工智能生成的文本对各个领域的组织都提出了挑战,包括学术界和新闻界等。生成式AI与大语言模型根据短描述来进行内容生成的能力,产生了一个问题:这篇文章/内容/作业/图像到底是由人类创作的,还是AI创作的?虽然 LL…...
Clion中怎么切换不同的程序运行
如下图,比如这个文件夹下面有那么多的项目: 那么我想切换不同的项目运行怎么办呢?如果想通过下图的Edit Configurations来设置是不行的: 解决办法: 如下图,选中项目的CMakeLists.txt,右键再点击…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
小木的算法日记-多叉树的递归/层序遍历
🌲 从二叉树到森林:一文彻底搞懂多叉树遍历的艺术 🚀 引言 你好,未来的算法大神! 在数据结构的世界里,“树”无疑是最核心、最迷人的概念之一。我们中的大多数人都是从 二叉树 开始入门的,它…...
如何在Windows本机安装Python并确保与Python.NET兼容
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
