赞
踩
年末出大坑,目前博主项目中对外提供的设备接口库涉及到网络通信,部分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)
- {
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。