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
相关产品推荐
相关产品推荐

