You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ESP32(IDF框架)HTTP POST字符与二进制数据上传速度差异问题

问题分析与解决方案

核心问题原因

你的代码存在关键错误:处理二进制文件时,使用strlen(post_data)获取POST数据长度。二进制文件中必然包含\0(空字符),strlen会在遇到第一个\0时停止计数,导致实际发送的payload远小于读取的4KB。这直接解释了Wireshark观测到的TCP payload从1440字节骤降到167字节的现象——每次POST仅发送到第一个\0为止的数据,频繁的小数据包触发TCP拥塞控制,大幅拉低传输速度。而字符文件几乎不含\0,strlen能正确返回完整的4KB长度,因此传输效率正常。

修复后的代码

修改file_operations函数

static void file_operations(void) {
    static FILE *file;
    static size_t read_bytes;
    static const char *directory = "/usb/esp";
    static const char *file_path = "/usb/esp/book.bin";

    file = fopen(file_path, "rb");
    if (!file) {
        // 新增:处理文件打开失败的情况
        return;
    }

    while (1) {
        // 移除memset:二进制数据无需初始化,fread会直接覆盖缓冲区
        read_bytes = fread(buffer, 1, sizeof(buffer), file);
        if (read_bytes <= 0) {
            break;  // 读取完毕或出错
        } else {
            err = post_rest_function(read_bytes); // 传递实际读取的字节数
        }
    }
    fclose(file);
}

修改post_rest_function函数

static esp_err_t post_rest_function(size_t data_len) {
    esp_http_client_set_post_field(client, buffer, data_len); // 使用实际读取的长度,而非字符串长度
    esp_err_t err = esp_http_client_perform(client);
    return err;
}

额外优化建议

  • 移除buffer[8191] = '\0';:二进制数据不需要空字符结尾,该操作会破坏缓冲区末尾的有效数据
  • 完善错误处理:增加esp_http_client_perform返回错误时的重试逻辑,提升代码健壮性
  • 保留TCP长连接:你已开启keep_alive_enable = 1,该设置可避免每次POST重新建立TCP连接的开销,无需修改

内容的提问来源于stack exchange,提问作者siddharth09

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 19:22:02