前言:
年末出大坑,目前博主項目中對外提供的設備接口庫涉及到網絡通信,部分HTTP請求概率性出現【CURLE_RECV_ERROR】問題。博主使用的是libcurl第三方庫進行http請求,由於網上沒有查到相關資料,下面記錄一下,本次問題分析和解決辦法,希望能給其他人提供解決思路。
問題定位:
通過Wireshark抓包,我對比了正常時候的HTTP流和異常時候的HTTP流。
異常HTTP流
正常HTTP流
當出現【CURLE_RECV_ERROR】問題時,客戶端向服務器發送POST請求,服務器未響應,6次TCP重傳無響應後,【libcurl】判定HTTP數據接收失敗。
我將數據包發聵給服務端研發人員,最後平臺擴大了連接池設置予以解決。
容錯方法
通過問題定位,已經能確定是服務器的問題,在問題還未解決的情況下,我這邊找到一個容錯方法,即CURL句柄先調用其它正常的接口後,再調用出問題的接口,能收到正常返回。
我這邊貼上容錯代碼:
QCARD_CURL *pHandle = (QCARD_CURL *)hCurlHandle;
char pcUrlGetIssue[128] = {0}, pcParameter[1024] = {0};
CURL *curl_handle = 0;
CURLcode res = CURLE_OK;
int ret = 0;
sprintf(pcUrlGetIssue, "http://%s/fillqkey/distrQKeyByBlock", pHandle->pcSystenAddr);
curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_URL, pcUrlGetIssue);//set down load url
curl_easy_setopt(curl_handle, CURLOPT_POST, 1);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, pHandle);//set download file
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, read_head_fun);//set call back fun
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);//設定爲不驗證證書和host
if(pHandle->uiTimeOut)
{
curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, pHandle->uiTimeOut);
}
sprintf(pcParameter, "deviceId=%s&unitId=%s&perBlockSeq=%d&devAuthCode=%s", pcStoreId, pcUnitId, *puiperBlockSeq, pcMacCode);
curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, pcParameter);
memset(pHandle->pcError, 0, sizeof(pHandle->pcError));
/* 容錯:CURLE_RECV_ERROR */
if(1)
{
curl_easy_setopt(curl_handle, CURLOPT_URL, "http://112.27.xx.xxx:xxxxx/fillqkey/createFillQKeyTask");//set down load url
res = curl_easy_perform(curl_handle);
curl_easy_setopt(curl_handle, CURLOPT_URL, pcUrlGetIssue);//set down load url
QCARD_FREE(pHandle->msg);
}
res = curl_easy_perform(curl_handle);
if(res != CURLE_OK)
{