ESP32如何准确获取HTTP文件下载请求的实际耗时
问题原因
你当前统计到的耗时偏高是因为esp_http_client_perform覆盖了HTTP请求全链路的所有环节耗时:包括DNS解析、TCP连接建立、TLS握手(HTTPS场景)、HTTP请求发送、等待服务器响应、接收响应头+响应体的全部时间,和你在Linux上单独统计的纯文件下载(仅响应体传输)耗时不在同一个统计维度,所以差异明显。
解决方案
通过ESP-IDF原生的esp_http_client事件回调机制,精准抓取文件下载阶段的起止时间点即可实现纯下载耗时统计,具体实现如下:
- 先定义用于计时的全局/静态变量,避免跨事件回调丢失数据:
// 下载起止时间戳 static struct timeval dl_start, dl_end; // 下载状态标志,避免重复计时 static bool is_downloading = false; // 最终统计的下载耗时(单位:微秒) static int64_t download_time_us = 0;
- 在你已注册的HTTP事件回调函数中,新增对应事件的计时逻辑:
esp_err_t _http_event_handler(esp_http_client_event_t *evt) { switch(evt->event_id) { // 响应头接收完成,即将开始传输响应体(文件内容),启动计时 case HTTP_EVENT_ON_HEADERS_FINISHED: gettimeofday(&dl_start, NULL); is_downloading = true; break; // 首次收到响应体数据时启动计时,适配无HTTP_EVENT_ON_HEADERS_FINISHED的旧版本ESP-IDF case HTTP_EVENT_ON_DATA: if (!is_downloading) { gettimeofday(&dl_start, NULL); is_downloading = true; } // 原有接收数据的逻辑保留即可 break; // 整个响应接收完成,停止计时 case HTTP_EVENT_ON_FINISH: if (is_downloading) { gettimeofday(&dl_end, NULL); download_time_us = ((int64_t)dl_end.tv_sec * 1000000L + dl_end.tv_usec) - ((int64_t)dl_start.tv_sec * 1000000L + dl_start.tv_usec); is_downloading = false; printf("纯文件下载耗时:%lld us\n", download_time_us); } break; // 请求异常时重置标志位,避免下次请求计时出现脏数据 case HTTP_EVENT_ERROR: is_downloading = false; break; // 你原有其他事件的处理逻辑保留即可 default: break; } return ESP_OK; }
注意事项
- 如果你不需要统计响应头接收完成到第一个数据到达的等待时间,只统计实际数据传输的耗时,仅保留
HTTP_EVENT_ON_DATA里的计时启动逻辑即可,统计结果会更贴近实际下载传输耗时。 - 统计前建议先做一次预请求建立连接预热,排除DNS缓存、连接复用等因素的干扰,测试结果会更稳定。
内容的提问来源于stack exchange,提问作者dax
相关产品推荐
相关产品推荐

