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

ESP32通过HTTP POST传输SD卡WAV文件损坏问题求助

问题根源

你的错误出在为WAV调整代码时修改了缓冲区的类型,和int16_t转uint8_t的强制转换没有关系:

  • int16_t是2字节长度的类型,你声明int16_t buff2[remainder+1]时,整个缓冲区的实际字节长度是2*(remainder+1),后续用sizeof(buff2)-1计算读取、发送长度时,实际读取和发送的字节数远大于你预期的remainder,多出来的部分是内存里的随机垃圾数据,直接导致传输后的文件体积变大、内容损坏。
  • 额外的隐性问题:你没有给POST请求加Content-Type: application/octet-stream头,Node-RED默认会把请求体当成文本内容处理,遇到WAV里的非ASCII字节时会做转义,也会导致文件损坏。

解决方法

WAV本质就是普通的二进制字节流,传输时不需要关心它内部存储的是int16_t还是其他格式,直接按字节读取传输即可,完全可以复用你传输文本文件的代码逻辑,只需要做2处调整:

  1. 不要修改缓冲区类型,保持用char或者uint8_t类型的缓冲区即可
  2. 调用http.POST之前添加二进制内容类型的请求头

修正后的核心代码示例

// 传输均等大小的分片
if (num_of_uploads > 0)
{
  uint8_t buff1[max_upload_size] = {}; // 二进制传输不需要额外预留结束符位置
  for (i = 0; i < num_of_uploads; i++)
  {
    fread(buff1, max_upload_size, 1, fp);
    http.addHeader("File_name", "test.wav");
    // 声明内容为二进制流,避免服务端转码
    http.addHeader("Content-Type", "application/octet-stream");
    int httpResponseCode = http.POST(buff1, max_upload_size);
  }
}
// 传输剩余的字节
if (num_of_uploads_mod > 0)
{
  int remainder = num_of_uploads_mod;
  uint8_t buff2[remainder] = {};
  fread(buff2, remainder, 1, fp);
  http.addHeader("File_name", "test.wav");
  http.addHeader("Content-Type", "application/octet-stream");
  int httpResponseCode = http.POST(buff2, remainder);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:06:04