GAT1400---基於libcurl庫的開發

一、curl庫的移植

前面我們已經講了,gat1400是通過http協議進行數據的交互,所以我們自然而然的想到了curl。

curl 是常用的命令行工具,用來請求 Web 服務器。cURL支持的通信協議有FTPFTPSHTTPHTTPSTFTPSFTPGopherSCPTelnet、DICT、FILELDAP、LDAPS、IMAPPOP3SMTPRTSP(摘自百度百科)。

curl下載:https://curl.haxx.se/download.html  

注:老版的curl不支持openssl.1.1加密庫,所以儘量下載高版本。

我們要的當然是curl的libcurl庫。

tar -xzvf curl-7.69.1.tar.gz
cd curl-7.69.1/
./configure --host=arm-hisiv500-linux  //交叉編譯環境
make
make install

在lib/.libs/目錄下有

libcurl.so  libcurl.so.4 libcurl.so.4.6.0三個動態庫(前兩個爲軟連接)以及libcurl.a一個靜態庫文件。

二、curl庫的開發

由於gat1400數據量比較大而且圖片需要進行basese64的編碼,在人流量密集的場合,如果我們還是使用一條一條數據往服務器丟會導致數據處理不過來,所以我們需要調用curl的異步機制。

看我的代碼

void *gat1400_dev_send_task(void *buf)
{
	int32_t index,count;
	struct list * plist;
	struct le *ple;
	CURL *CurlArray[CACHE_MAX_ID*4] = {NULL};
	GAT1400_SEND_S *pdata[CACHE_MAX_ID*4] = {NULL};
	
	gat1400_init_send();
		
	plist = &gat1400_list.send_list;
	
	while(gat1400_mod.runing && get_dev_online())
	{
	
		pthread_mutex_lock(&gat1400_list.send_mutex);
		count = list_count(plist);
		pthread_mutex_unlock(&gat1400_list.send_mutex);
		
		if(count < 1)
		{
			usleep(100000);
			continue;
		}
		
		DBG_INFO("send count:%d\n",count);
		count = (count > 120 ? 120 : count);
		
		for (index = 0; index < count; index++)
		{
			ple = list_head(plist);
			pdata[index] = ple->data;

			CurlArray[index] = curl_easy_handler(pdata[index]->http,pdata[index]->data,2000);
			curl_multi_add_handle(gat1400_list.multi_handle, CurlArray[index]);

			pthread_mutex_lock(&gat1400_list.send_mutex);
			if(ple)
			{
				list_unlink(ple);
			}
			pthread_mutex_unlock(&gat1400_list.send_mutex);
			
		}
		
		lib_send_images(gat1400_list.multi_handle);
		
		//釋放數據
		for(index = 0; index < count; index++)
		{
		
			curl_multi_remove_handle(gat1400_list.multi_handle, CurlArray[index]);
			curl_easy_cleanup(CurlArray[index]);
			
			free(pdata[index]->data);
			free(pdata[index]);
		}
		
	}
	
	gat1400_uninit_send();
	
	return NULL;
}

/*********************
封裝初始化easy句柄
***********************/
CURL * curl_easy_handler(const char *sUrl,
						 char *data,
                         unsigned int uiTimeout)
{
	char  http_header[512] = {0};
	struct curl_slist *list = NULL;

	if(NULL == sUrl || NULL == data )
	{
		return NULL;
	}
	
    CURL * curl = curl_easy_init();

    curl_easy_setopt(curl, CURLOPT_URL, sUrl);
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
	curl_easy_setopt(curl,CURLOPT_POST,1); //設置問非0表示本次操作爲post
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
	curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,gat1400_null_cb); 	//對返回的數據進行操作的函數地址
	//header
	list = curl_slist_append(list, "Content-Type: application/json");
	list = curl_slist_append(list, "Accept:application/json");
	sprintf(http_header,GAT_HEADER_MSG,gat1400_mod.devid);
	list = curl_slist_append(list, http_header);
	curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
	
	if (uiTimeout > 0)
    {
        curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, uiTimeout);
    }

    return curl;
}

int32_t lib_send_images(CURLM * multi_handle)
{
	int res = 0;
	int max_fd = 50;
	int return_code;
    fd_set fd_read;
    fd_set fd_write;
    fd_set fd_except;
	struct timeval tv;
	
	tv.tv_sec = 3;
	tv.tv_usec = 0;

	if(NULL == multi_handle)
	{
		return GAT_False;
	}

	while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &res))
	{
		DBG_ERR("res err:%d\n",res);
	}

	while (res)
    {
    	
	    FD_ZERO(&fd_read);
	    FD_ZERO(&fd_write);
	    FD_ZERO(&fd_except);
		
		curl_multi_fdset(multi_handle, &fd_read, &fd_write, &fd_except, &max_fd);
		return_code = select(max_fd + 1, &fd_read, &fd_write, &fd_except, &tv);

		if (-1 == return_code)
		{
			break;
		}
		else
		{
			while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(multi_handle, &res))
			{
				DBG_ERR("res err:%d\n",res);
			}
		}

	}
	
	return GAT_True;
}

int32_t gat1400_init_send()
{
	DBG_INFO("GAT1400 start run send task\n");
	
	comm_set_thread_name("gat1400 send task");
	
	gat1400_list.multi_handle = curl_multi_init();
		
	return GAT_True;
}


int32_t gat1400_uninit_send()
{

	gat1400_mod.dev_send_thread_id = 0;
	curl_multi_cleanup(gat1400_list.multi_handle);
	
	DBG_INFO("gat1400 send task exit\n");
	return GAT_True;
}

  代碼核心通過

curl_multi_init();     //開始

CURL * curl_easy_handler(const char *sUrl, char *data, unsigned int uiTimeout);

curl_multi_add_handle(CURLM *multi_handle, CURL *curl_handle);

curl_multi_perform(CURLM *multi_handle, int *running_handles);

curl_multi_remove_handle(CURLM *multi_handle, CURL *curl_handle);

curl_easy_cleanup(CURL *curl);

curl_multi_cleanup(CURLM *multi_handle);    //結束

流程對數據進行上傳處理。

我在800wIPC相機上測試,在吃掉80M內存情況下,1s進行30張人臉上傳數據是沒有壓力的。

有錯誤請留言,謝謝。

                                  bob  2020-04-07

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章