esp-http-client 发送 chunked 数据

测试 HTTP 发送数据速率

static void http_iperf(void)
{
    esp_http_client_config_t config = {
        .url = "http://httpbin.org/post",
    };
    esp_http_client_handle_t client = esp_http_client_init(&config);

    esp_http_client_set_method(client, HTTP_METHOD_POST);
    int count = 50;
    size_t chunk1_data_size = 1024 * 50;
    esp_http_client_open(client, chunk1_data_size * count);

    char *chunk1_data = malloc(chunk1_data_size);
    uint32_t start_timer = esp_log_timestamp();
    int content_length, read_len;
    char *buffer = malloc(1024);
    ESP_LOGW(TAG, "---send begin---");
    for (int i = 0; i < count; ++i) {
        int wlen = esp_http_client_write(client, chunk1_data, chunk1_data_size);
        if (wlen < 0) {
            ESP_LOGE(TAG, "Write failed");
        }
        ESP_LOGI(TAG, "write_size: %d", wlen);
        content_length = esp_http_client_fetch_headers(client);
        // ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %d", esp_http_client_get_status_code(client), content_length);
        // read_len = esp_http_client_read(client, buffer, 1024);
        // ESP_LOGI(TAG, "read_len: %d", read_len);

    }
    
    int cost_time = (esp_log_timestamp() - start_timer)/1000;
    ESP_LOGW(TAG, "send end, cost time %d, speed %dKB/s", cost_time, chunk1_data_size * count/cost_time/1024);
    esp_http_client_cleanup(client);
}

通过 HTTP 发送 chunked 数据

相关 API

/**
 * @brief     This function will write data to the HTTP connection previously opened by esp_http_client_open()
 *
 * @param[in]  client  The esp_http_client handle
 * @param      buffer  The buffer
 * @param[in]  len     This value must not be larger than the write_len parameter provided to esp_http_client_open()
 *
 * @return
 *     - (-1) if any errors
 *     - Length of data written
 */
int esp_http_client_write(esp_http_client_handle_t client, const char *buffer, int len);
esp_err_t esp_http_client_open(esp_http_client_handle_t client, int write_len)
{
    client->post_len = write_len;
    esp_err_t err;
    if ((err = esp_http_client_connect(client)) != ESP_OK) {
        return err;
    }
    if ((err = esp_http_client_request_send(client, write_len)) != ESP_OK) {
        return err;
    }
    return ESP_OK;
}
static esp_err_t esp_http_client_request_send(esp_http_client_handle_t client, int write_len)
{
    int first_line_len = 0;
    if (!client->first_line_prepared) {
        if ((first_line_len = http_client_prepare_first_line(client, write_len)) < 0) {
            return first_line_len;
        }
        client->first_line_prepared = true;
        client->header_index = 0;
        client->data_written_index = 0;
        client->data_write_left = 0;
    }
    ...

static int http_client_prepare_first_line(esp_http_client_handle_t client, int write_len)
{
    if (write_len >= 0) {
        http_header_set_format(client->request->headers, "Content-Length", "%d", write_len);
    } else {
        esp_http_client_set_header(client, "Transfer-Encoding", "chunked");
        esp_http_client_set_method(client, HTTP_METHOD_POST);
    }
    ...

测试代码

idf 版本:v4.3.1

static void http_post_chunked_data()
{
    esp_http_client_config_t config = {
		.url = "https://siva.how2go.cn/",
		.method = HTTP_METHOD_POST, // This is NOT required. write_len < 0 will force POST anyway
	};
    char buffer[1024] = {0};
	esp_http_client_handle_t client = esp_http_client_init(&config);

	esp_err_t err = esp_http_client_open(client, -1); // write_len=-1 sets header "Transfer-Encoding: chunked" and method to POST
	if (err != ESP_OK) {
		ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
		return;
	}

	// Post some data
	esp_http_client_write(client, "5", 1); // length
	esp_http_client_write(client, "\r\n", 2);
	esp_http_client_write(client, "Hello", 5); // data
	esp_http_client_write(client, "\r\n", 2);
	esp_http_client_write(client, "6", 1); // length
	esp_http_client_write(client, "\r\n", 2);
	esp_http_client_write(client, " World!", 7);  // data
	esp_http_client_write(client, "\r\n", 2);
	esp_http_client_write(client, "0", 1);  // end
	esp_http_client_write(client, "\r\n", 2);
	esp_http_client_write(client, "\r\n", 2);

	// After the POST is complete, you can examine the response as required using:
	int content_length = esp_http_client_fetch_headers(client);
    ESP_LOGI(TAG, "content_length: %d, status_code: %d", content_length, esp_http_client_get_status_code(client));

	int read_len = esp_http_client_read(client, buffer, 1024);
    ESP_LOGI(TAG, "receive %d data from server: %s", read_len, buffer);
	esp_http_client_close(client);
	esp_http_client_cleanup(client);
}

运行结果如下:

I (7541) wifi:new:<1,0>, old:<1,0>, ap:<255,255>, sta:<1,0>, prof:1
I (7541) wifi:state: init -> auth (b0)
I (7551) wifi:state: auth -> assoc (0)
I (7561) wifi:state: assoc -> run (10)
I (7601) wifi:connected with iot, aid = 44, channel 1, BW20, bssid = 30:a2:c2:70:27:88
I (7601) wifi:security: WPA2-PSK, phy: bgn, rssi: -25
I (7601) wifi:pm start, type: 1

I (7681) wifi:AP's beacon interval = 102400 us, DTIM period = 1
I (8501) esp_netif_handlers: example_connect: sta ip: 192.168.3.18, mask: 255.255.255.0, gw: 192.168.3.1
I (8501) example_connect: Got IPv4 event: Interface "example_connect: sta" address: 192.168.3.18
I (9501) example_connect: Got IPv6 event: Interface "example_connect: sta" address: fe80:0000:0000:0000:32ae:a4ff:fe80:663c, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (9501) example_connect: Connected to example_connect: sta
I (9511) example_connect: - IPv4 address: 192.168.3.18
I (9511) example_connect: - IPv6 address: fe80:0000:0000:0000:32ae:a4ff:fe80:663c, type: ESP_IP6_ADDR_IS_LINK_LOCAL
I (9521) HTTP_CLIENT: Connected to AP, begin http example
I (10511) HTTP_CLIENT: content_length: 355, status_code: 200
I (10511) HTTP_CLIENT: receive 355 data from server: {
  "args": {}, 
  "data": "Hello World", 
  "files": {}, 
  "form": {}, 
  "headers": {
    "Host": "httpbin.org", 
    "Transfer-Encoding": "chunked", 
    "User-Agent": "ESP32 HTTP Client/1.0", 
    "X-Amzn-Trace-Id": "Root=1-61c2da80-42eba34009b4325d137cefc6"
  }, 
  "json": null, 
  "origin": "20.187.154.207", 
  "url": "http://httpbin.org/post"
}

参考链接

Chunked transfer encoding
esp_http_client - How to POST Chunked Data
HTTP Stream

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值