我目前正試圖使用ESP32獲得一個HTTP請求(下載1個檔案)需要完成的時間,但API沒有這方面的選項。我可以設定一個超時,但我不知道它需要完成的真實時間。
我試著獲取執行函式esp_err_t err = esp_http_client_perform(client);之后和之前的差異時間。
struct timeval start,end。
esp_http_client_config_t config = {
.url = DOWNLOAD_FILE_URL,
.event_handler = _http_event_handler,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
gettimeofday(&start, NULL)。
esp_err_t err = esp_http_client_perform(client)。
gettimeofday(&end, NULL)。
int64_t time_us = (((int64_t)end.tv_sec * 1000000L (int64_t)end. tv_usec)-((int64_t)start.tv_sec * 1000000L (int64_t)start.tv_usec))。
但是對于我正在做的事情來說,回傳的值似乎太多了(下載一個小檔案&;我在Linux機器上用curl做的,只花了20ms) :
Time : 1305909 uS
我認為esp_http_client_perform(client)函式可能在做許多其他事情,而不僅僅是下載檔案,這就是為什么我沒有得到下載檔案所需的時間。
你有什么辦法可以讓我只得到下載檔案所需的時間嗎?
非常感謝您的幫助。
uj5u.com熱心網友回復:
Hi Mate 我建議使用網路時間協議。這是一個標準的互聯網協議(IP),用于通過網路將計算機時鐘同步到某個參考點。 該協議可用于將所有聯網的設備同步到協調世界時(UTC)。 NTP將計算機的時鐘設定為UTC,任何本地時區的偏移或日光節約時間的偏移都由客戶端應用。通過這種方式,客戶可以與服務器同步,而不受地點和時區差異的影響。 服務器在123埠使用用戶資料報協議(UDP)。 然后,客戶端向NTP服務器傳輸一個請求包。 作為對該請求的回應,NTP服務器會發送一個時間戳資料包。
請試一試這段代碼:
const char *ssid = "***********"/span>;
const char *password = "***********";
const long utcOffsetInSeconds = 0;
char daysOfTheWeek[7][12] = {"周日", "周一", "星期二"/span>, "星期三"/span>, "星期四"/span>, "星期五"/span>, "星期六"/span>}。
//定義NTP客戶端以獲取時間。
WiFiUDP ntpUDP。
NTPClient timeClient(ntpUDP, "pool.ntp.org"/span>, utcOffsetInSeconds)。
void setup(){
Serial.begin(115200)。
WiFi.begin(ssid, password)。
while ( WiFi.status() != WL_CONNECTED ) {
delay ( 500 ) 。
Serial.print ( "。" )。
}
timeClient.begin()。
}
void loop() {
timeClient.update()。
Serial.print(daysOfTheWeek[timeClient.getDay()])。
Serial.print(", ")。
Serial.print(timeClient.getHours())。
Serial.print(" :");
Serial.print(timeClient.getMinutes())。
Serial.print(":")。
Serial.println(timeClient.getSeconds())。
//Serial.println(timeClient.getFormattedTime());
delay(1000)。
}
注意:該行:
const long utcOffsetInSeconds =0;
設定UTC時間(基本上是格林威治時間,沒有光照時間的偏移),如果你愿意,可以設定你自己的偏移量,單位是格林威治時間的秒。 這里有一篇很好的文章。https://www.instructables.com/Getting-Time-From-Internet-Using-ESP8266-NTP-Clock/
如果你得到了兩個讀數,并且你做出了這兩個讀數之間的差異,你就得到了操作的持續時間,并且(非常重要,因為我們正在談論網路操作),為后續分析提供了時間參考。
我希望這對你有幫助,祝你好運
。uj5u.com熱心網友回復:
首先,呼叫gettimeofday()并計算差值,對于這樣一個簡單的任務來說,IMHO太費勁了。呼叫esp_timer_get_time()以獲得自啟動以來的微秒數,并在此基礎上計算持續時間,這樣會更簡單。
其次,你給你的 HTTP 客戶端提供的自定義事件處理程式( 最后,請注意,如果你正在進行HTTPS下載,那么可憐的小ESP32將花費大量時間進行TLS握手加密計算。
標籤:_http_event_handler)會在 HTTP 下載中的每個 相關事件中被呼叫,所以使用它來查看每個步驟需要多長時間。我已經轉換為毫秒,因為這似乎是衡量下載事件的正確單位尺度。
uint64_t start_time。
esp_http_client_config_t config = {
.url = DOWNLOAD_FILE_URL,
.event_handler = _http_event_handler,
.user_data = &start_time,
};
esp_http_client_handle_t client = esp_http_client_init(&config)。
start_time = esp_timer_get_time()。
esp_err_t err = esp_http_client_perform(client)。
ESP_LOGI(TAG, "Total time %u ms", (uint32_t)((esp_timer_get_time() - start_time) / 1000) 。)
...
esp_err_t _http_event_handle(esp_http_client_event_t *evt) {
uint32_t duration_ms = (uint32_t) ((esp_timer_get_time() - *(uint64_t*) (evt-> user_data) / 1000)。)
switch(evt-> event_id) {
case HTTP_EVENT_ERROR:
ESP_LOGI(TAG, "HTTP_EVENT_ERROR %u ms"/span>, duration_ms)。
break。
case HTTP_EVENT_ON_CONNECTED:
ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED %u ms"/span>, duration_ms)。
break。
case HTTP_EVENT_HEADER_SENT。
ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT %u ms"/span>, duration_ms)。
break。
case HTTP_EVENT_ON_HEADER:
ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER %u ms"/span>, duration_ms)。
printf("%.*s", evt->data_len, (char*)evt-> data);
break。
case HTTP_EVENT_ON_DATA:
ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA, len=%d %u ms", evt-> data_len, duration_ms)。
break。
case HTTP_EVENT_ON_FINISH。
ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH %u ms", duration_ms)。)
break。
case HTTP_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED %u ms"/span>, duration_ms)。
break。
}
return ESP_OK。
}
