概念先知道
- DELETE:HTTP 方法之一,语义是“删除 URL 指定的资源”,常用于删除设备、清空数据。
- 一般不带请求体:DELETE 的目标在 URL 里,多数实现不需要 body。
- 响应:删除成功常见返回
200 OK或204 No Content。 - RESTful:用 HTTP 方法表达操作(GET 查、POST 增、PUT 改、DELETE 删)的接口风格,本页方法适合这类接口。
例程功能简介
SDK 的 wifi_http 例程未演示 PUT/DELETE,本页自编示例基于其 wifi_http_client.c 的用法编写:
- 拿到 IP 后创建
http_delete_task; - 构造
https_client_request:method = HTTP_DELETE、url = HTTP_URL; - 调用
https_client_request同步等待响应,response_cb打印返回内容; - 每 5 秒重复一次,方便观察。
- 同族参考:GET/POST 用官方
wifi_http例程(GET / POST);更新资源见自编 PUT;加密版见 HTTPS。
操作步骤
SDK 的 wifi_http 例程只演示 GET/POST,本页在其骨架上编写 DELETE(标注自编示例)。先进入目录:
cd examples/wifi/sta/wifi_http用下面的自编 main.c 覆盖例程目录里的 main.c(记得把 HTTP_URL 改成你的测试服务器地址):
统一填写 bl616:
make CHIP=bl616 BOARD=bl616dk按住 BOOT 短按 EN/RST 进入下载模式后烧录:
make flash CHIP=bl616 COMX=/dev/ttyUSB0串口助手波特率 2000000,连接路由器后程序自动执行 DELETE:请求 HTTP_URL 删除指定资源并打印服务器响应。可在电脑的 RESTful 测试服务上观察。
wifi_sta_connect Your_SSID 12345678代码执行流程
HTTP DELETE 从启动到响应的完整流程如下:
例程调用的 API 介绍
https_client_request(&req, timeout, user_data)
同步发起一次 HTTP/HTTPS 请求,req.method = HTTP_DELETE。
参数:
&req:struct https_client_requesttimeout:超时毫秒数(示例 5000)user_data:透传数据
返回值:>= 0 成功;< 0 失败
req.url()
DELETE 的资源地址,例如 http://192.168.1.2:8080/api/device/1。资源 ID 通常拼在 URL 末尾。
参数:
url:const char *,完整 URL
返回值:无(结构体字段)
response_cb(rsp, final_data, user_data)
响应回调,打印服务器返回内容(通常为空 body 或简短 JSON)。
参数:
rsp:struct http_response,含recv_buf与data_lenfinal_data:HTTP_DATA_MORE/HTTP_DATA_FINALuser_data:用户数据
返回值:无
完整代码
以下为自编示例 main.c(基于 SDK wifi_http 例程骨架与 https_client.h 接口编写,非 SDK 自带文件),默认折叠,点击展开:
📜 点击展开 自编 http_delete main.c 完整代码
/*
* 自编示例:HTTP DELETE(基于 SDK https_client.h)
* 使用方法:
* 1. 用本文件覆盖 examples/wifi/sta/wifi_http/main.c;
* 2. 把 HTTP_URL 改成你的测试服务器地址;
* 3. make CHIP=bl616 BOARD=bl616dk && make flash CHIP=bl616 COMX=/dev/ttyUSB0;
* 4. 串口执行 wifi_sta_connect <SSID> <密码>,程序自动发送 DELETE。
*/
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include <string.h>
#include <lwip/tcpip.h>
#include <lwip/sockets.h>
#include <lwip/netdb.h>
#include "wifi_mgmr_ext.h"
#include "fhost_api.h"
#include "wifi_mgmr.h"
#include "bflb_irq.h"
#include "bflb_uart.h"
#include "rfparam_adapter.h"
#include "async_event.h"
#include "mm.h"
#include "board.h"
#include "shell.h"
#include "https_client.h"
#define DBG_TAG "MAIN"
#include "log.h"
#define HTTP_URL "http://192.168.1.2:8080/api/device/1"
static volatile uint32_t wifi_state = 0;
static struct bflb_device_s *uart0;
extern void shell_init_with_task(struct bflb_device_s *shell);
static int log_output(void *ptr, size_t size)
{
size_t i;
for (i = 0; i < size; i++) {
putchar(((char *)ptr)[i]);
}
return (int)i;
}
static void response_cb(struct http_response *rsp,
enum http_final_call final_data,
void *user_data)
{
log_output(rsp->recv_buf, rsp->data_len);
if (final_data == HTTP_DATA_FINAL) {
LOG_I("\r\n[response finished]\r\n");
}
}
void wifi_event_handler(async_input_event_t ev, void *priv)
{
switch (ev->code) {
case CODE_WIFI_ON_GOT_IP:
wifi_state = 1;
LOG_I("Got IP\r\n");
break;
case CODE_WIFI_ON_DISCONNECT:
wifi_state = 0;
LOG_I("WiFi disconnected\r\n");
break;
default:
break;
}
}
static void http_delete_task(void *param)
{
struct https_client_request req;
int ret;
/* 等待 Wi-Fi 拿到 IP */
while (!wifi_state) {
vTaskDelay(pdMS_TO_TICKS(200));
}
while (1) {
memset(&req, 0, sizeof(req));
req.method = HTTP_DELETE;
req.url = HTTP_URL;
req.protocol = "HTTP/1.1";
req.response = response_cb;
LOG_I("HTTP DELETE to %s\r\n", HTTP_URL);
ret = https_client_request(&req, 5 * 1000, "HTTP DELETE");
if (ret < 0) {
LOG_E("http delete request fail ret:%d\r\n", ret);
} else {
LOG_I("Http DELETE request server success\r\n");
}
vTaskDelay(pdMS_TO_TICKS(5000));
}
}
static void wifi_start_firmware_task(void *param)
{
LOG_I("Starting wifi ...\r\n");
async_register_event_filter(EV_WIFI, wifi_event_handler, NULL);
wifi_task_create();
LOG_I("Starting fhost ...\r\n");
fhost_init();
vTaskDelete(NULL);
}
int main(void)
{
board_init();
uart0 = bflb_device_get_by_name("uart0");
shell_init_with_task(uart0);
if (0 != rfparam_init(0, NULL, 0)) {
LOG_I("PHY RF init failed!\r\n");
return 0;
}
tcpip_init(NULL, NULL);
xTaskCreate(wifi_start_firmware_task, "wifi init", 1024, NULL, 10, NULL);
xTaskCreate(http_delete_task, "http del", 2048, NULL, 11, NULL);
vTaskStartScheduler();
while (1) {
}
}FAQ
DELETE 返回 405 Method Not Allowed
服务器或接口不支持 DELETE;确认接口文档允许删除,或换支持 RESTful 的测试服务。部分 CDN/静态服务器只支持 GET,会拒绝其他方法。
删除后再次请求仍成功
部分接口设计成“幂等删除”(重复删除也返回成功);是否真的删除要看服务器业务逻辑与返回的状态码,不能只看请求是否连通。
遇到问题?
如有其他问题,请到统一的提问与讨论区:Ai-Thinker Discussions
📜 点击展开 wifi_http/wifi_http_client.c 完整代码
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <lwip/api.h>
#include <lwip/arch.h>
#include <lwip/opt.h>
#include <lwip/inet.h>
#include <lwip/errno.h>
#include <netdb.h>
#include "shell.h"
#include "utils_getopt.h"
#include "bflb_mtimer.h"
#include "https_client.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
#endif
static int payload_cb(int sock, struct http_request *req, void *user_data)
{
const char *content[] = {
"foobar",
"chunked",
"last"
};
char tmp[64];
int i, pos = 0;
for (i = 0; i < ARRAY_SIZE(content); i++) {
pos += snprintf(tmp + pos, sizeof(tmp) - pos,
"%x\r\n%s\r\n",
(unsigned int)strlen(content[i]),
content[i]);
}
pos += snprintf(tmp + pos, sizeof(tmp) - pos, "0\r\n\r\n");
(void)zsock_send(sock, tmp, pos, 0);
return pos;
}
static int log_output(void *ptr, size_t size)
{
size_t i;
for (i = 0; i < size; i++) {
putchar(((char *)ptr)[i]);
}
return i;
}
static void response_cb(struct http_response *rsp,
enum http_final_call final_data,
void *user_data)
{
log_output(rsp->recv_buf, rsp->data_len);
if (final_data == HTTP_DATA_MORE) {
//printf("Partial data received (%zd bytes)\r\n", rsp->data_len);
} else if (final_data == HTTP_DATA_FINAL) {
//printf("All the data received (%zd bytes)\r\n", rsp->data_len);
}
}
#define PING_USAGE \
"wifi_http_test [url]\r\n" \
"\t url: url or dest server ip\r\n" \
static void wifi_test_http_client_init(int argc, char **argv)
{
int ret;
char *url;
struct https_client_request req;
if (argc < 2) {
printf("%s", PING_USAGE);
return;
}
/* get address (argv[1] if present) */
url = argv[1];
memset(&req, 0, sizeof(req));
req.method = HTTP_GET;
req.url = url;
req.protocol = "HTTP/1.1";
req.response = response_cb;
ret = https_client_request(&req, 3*1000, "IPv4 GET");
if (ret < 0) {
printf("http_client get request fail ret:%d\r\n", ret);
} else {
printf("Http client GET request server success\r\n");
}
const char *headers[] = {
"Transfer-Encoding: chunked\r\n",
NULL
};
memset(&req, 0, sizeof(req));
req.method = HTTP_POST;
req.url = url;
req.protocol = "HTTP/1.1";
req.payload_cb = payload_cb;
req.header_fields = headers;
req.response = response_cb;
ret = https_client_request(&req, 3*1000, "IPv4 POST");
if (ret < 0) {
printf("http_client post request fail ret:%d\r\n", ret);
} else {
printf("Http client POST request server success\r\n");
}
}
#ifdef CONFIG_SHELL
#include <shell.h>
int cmd_wifi_http_client(int argc, char **argv)
{
wifi_test_http_client_init(argc, argv);
return 0;
}
SHELL_CMD_EXPORT_ALIAS(cmd_wifi_http_client, wifi_http_test, wifi http client test);
#endif
