赞
踩
主要使用的几个api接口:
1、curl_easy_init
2、curl_slist_append
3、curl_formadd
4、curl_easy_setopt
5、curl_easy_perform
6、curl_easy_getinfo
7、curl_slist_free_all
8、curl_formfree
9、curl_easy_cleanup
下面代码中使用的一些libcurl选项,如果需要详细了解,可以访问 https://curl.se/libcurl/ 自行学习
typedef struct _stHttpUserInfo
{
int nOperation; /* 操作类型, 参考 HTTP_SEND_HEARTBIT */
int nSubOperation; /* 子操作类型, 参考 HTTP_UPLOADRESULT_TYPE_SNAPIMG */
int ucFlag; /* 用以区分头部还是内容部分,默认为0-->只需要body部分 */
int nSedSize; /* 发送数据大小 */
int nRcvBufLen; /* 缓冲区长度 */
int nRcvSize; /* 接收body数据大小 */
void *pRcvBuffer; /* 指向用户用来存储数据的buf */
void *pSendBuffer; /* 指向用户发送数据的buf */
}stHttpUserInfo;
typedef struct _stHttpClientInfo
{
int nClientPort; /* http服务器监听端口号 */
char szClientIP[32]; /* http服务器IP */
char szClientPath[64]; /* http服务器文件路径 */
char szUserName[32]; /* http服务器登录用户 */
char szUserPassWord[32]; /* http服务器登录密码 */
char szUrl[128]; /* http服务器url */
char szWorkDir[128]; /* 工作目录, 需要保存文件的路径 */
stHttpUserInfo stHttpUserHead;
stHttpUserInfo stHttpUserBody;
}stHttpClientInfo;
#define FREE(x) \
{\
if (NULL != x)\
{\
free(x);\
x = NULL;\
}\
}
/**************************************************************************
函数名称: httpClient_WriteBack
功能描述: http写数据回调
输入参数: IN void *pContents, http返回的数据
IN size_t size, 单个数据的大小
IN size_t nmemb, 数据的个数
OUT void *stream 存放接收消息的结构
输出参数: OUT void *stream 存放接收消息的结构
注 意 点: 返回值为接收的长度
***************************************************************************/
size_t httpClient_WriteBack(IN void *pContents, IN size_t size, IN size_t nmemb, OUT void *stream)
{
int nRealSize = 0;
char *pcTmp = NULL;
stHttpUserInfo *pstChunk = NULL;
if ((NULL == pContents) || (NULL == stream))
{
printf("[CURL]Invalid parameter\n");
return 0;
}
nRealSize = size * nmemb;
pstChunk = (stHttpUserInfo *)stream;
pcTmp = pstChunk->pRcvBuffer;
pstChunk->pRcvBuffer = (char *)realloc(pstChunk->pRcvBuffer, pstChunk->nRcvSize + nRealSize + 1);
if (NULL == pstChunk->pRcvBuffer)
{
FREE(pcTmp);
printf("[CURL]realloc memory failed, lenth[%d]\n", pstChunk->nRcvSize + nRealSize + 1);
return 0;
}
/* 因为需要保存之前的数据,所以realloc后不能memset */
memcpy((char *)pstChunk->pRcvBuffer + pstChunk->nRcvSize, (void *)pContents, (size_t)nRealSize);
pstChunk->nRcvSize += nRealSize;
return nRealSize;
}
/**************************************************************************
函数名称: Http_Client
功能描述: 发送http请求
输入参数: IN stHttpClientInfo *pstUserArg 客户端结构
输出参数:
注 意 点:
***************************************************************************/
Http_Client(IN stHttpClientInfo *pstUserArg)
{
int nRet = 0;
int timeout = 10; /* http请求的超时时间, 默认10s */
CURL *pstCurl = NULL;
CURLcode code = 0;
long response_code = -1;
struct curl_slist *pstHeaderlist = NULL;
struct curl_httppost *pstForm = NULL;
struct curl_httppost *pstLast = NULL;
/* 1. 初始化curl */
pstCurl = curl_easy_init();
if (NULL == pstCurl)
{
printf("[CURL]init curl fail\n");
return ERR_COMMON_NO_MEMORY;
}
/* 2. 初始化头信息 */
pstHeaderlist = curl_slist_append(pstHeaderlist, "Connection:keep-alive");
pstHeaderlist = curl_slist_append(pstHeaderlist, "Accept: */*");
pstHeaderlist = curl_slist_append(pstHeaderlist, "Cache-Control:no-cache");
pstHeaderlist = curl_slist_append(pstHeaderlist, "Expect:");
/* 根据类型填充表单 */
switch(pstUserArg->stHttpUserHead.nOperation)
{
/* 表单--数据流, pstUserArg->stHttpUserBody.pSendBuffer存放的字符串 */
case 0:
{
pstHeaderlist = curl_slist_append(pstHeaderlist, "Content-Type: multipart/form-data");
curl_formadd(&pstForm, &pstLast,
CURLFORM_COPYNAME, "json",
CURLFORM_PTRCONTENTS, pstUserArg->stHttpUserBody.pSendBuffer,
CURLFORM_END);
timeout = strlen(pstUserArg->stHttpUserBody.pSendBuffer)/(200 * 1024); /* 按照200k/s计算上传的超时时间 */
curl_easy_setopt(pstCurl, CURLOPT_HTTPPOST, pstForm); /* 替换表单数据 */
break;
}
/* 表单--文件流, pstUserArg->stHttpUserBody.pSendBuffer存放的文件绝对路径 */
case 1:
{
pstHeaderlist = curl_slist_append(pstHeaderlist, "Content-Type: multipart/form-data");
curl_formadd(&pstForm, &pstLast,
CURLFORM_COPYNAME, "file",
CURLFORM_FILE, pstUserArg->stHttpUserBody.pSendBuffer,
CURLFORM_END);
timeout = 60; /* 自行计算文件大小, 然后按照200k/s计算上传的超时时间 */
curl_easy_setopt(pstCurl, CURLOPT_HTTPPOST, pstForm); /* 替换表单数据 */
break;
}
/* get请求 */
case 2:
{
curl_easy_setopt(pstCurl, CURLOPT_HTTPGET, 1L);
timeout = 30;
break;
}
/* psot, body中存放json数据 */
case 3:
{
pstHeaderlist = curl_slist_append(pstHeaderlist, "Content-Type: application/json");
curl_easy_setopt(pstCurl, CURLOPT_POSTFIELDSIZE, strlen(pstUserArg->stHttpUserBody.pSendBuffer)); /* 设置上传数据的大小,也可以设置-1让libcurl使用strlen计算数据大小 */
curl_easy_setopt(pstCurl, CURLOPT_POSTFIELDS, pstUserArg->stHttpUserBody.pSendBuffer);
timeout = strlen(pstUserArg->stHttpUserBody.pSendBuffer)/(200 * 1024); /* 按照200k/s计算上传的超时时间 */
break;
}
default:
{
curl_easy_cleanup(pstCurl);
pstCurl = NULL;
curl_slist_free_all(pstHeaderlist);
pstHeaderlist = NULL;
printf("[CURL]not support msg type[%d]\n", pstUserArg->stHttpUserHead.nOperation);
return ERR_COMMON_NOT_SUPPORT;
}
}
curl_easy_setopt(pstCurl, CURLOPT_HTTPHEADER, pstHeaderlist);
/* 3. 初始化存放接收数据需要用到的缓存 */
pstUserArg->stHttpUserBody.nRcvBufLen = 0;
pstUserArg->stHttpUserBody.pRcvBuffer = (char *)calloc(1, 1);
if (NULL == pstUserArg->stHttpUserBody.pRcvBuffer)
{
printf("[CURL]calloc fail\n");
curl_formfree(pstForm);
pstForm = NULL;
curl_slist_free_all(pstHeaderlist);
pstHeaderlist = NULL;
curl_easy_cleanup(pstCurl);
pstCurl = NULL;
return ERR_COMMON_NO_MEMORY;
}
/* 4. 填充相关请求信息 */
if (NULL != strstr(pstUserArg->szUrl, "https")) /* 设定为不验证证书和HOST */
{
curl_easy_setopt(pstCurl, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(pstCurl, CURLOPT_SSL_VERIFYHOST, 0);
}
curl_easy_setopt(pstCurl, CURLOPT_URL, pstUserArg->szUrl); /* 设置URL路径 */
curl_easy_setopt(pstCurl, CURLOPT_NOSIGNAL, 1L); /* 屏蔽库内部由于多线程导致的信号中断 */
curl_easy_setopt(pstCurl, CURLOPT_WRITEFUNCTION, httpClient_WriteBack); /* 设置用于接收响应body的处理函数*/
curl_easy_setopt(pstCurl, CURLOPT_WRITEDATA, &pstUserArg->stHttpUserBody); /* 设置回调函数的第四个参数 */
if (1 == pstUserArg->stHttpUserHead.ucFlag)
{
pstUserArg->stHttpUserHead.nRcvBufLen = 0;
pstUserArg->stHttpUserHead.pRcvBuffer = (char *)calloc(1, 1);
if (NULL == pstUserArg->stHttpUserHead.pRcvBuffer)
{
printf("[CURL]calloc fail\n");
curl_formfree(pstForm);
pstForm = NULL;
curl_easy_cleanup(pstCurl);
pstCurl = NULL;
curl_slist_free_all(pstHeaderlist);
pstHeaderlist = NULL;
FREE(pstUserArg->stHttpUserBody.pRcvBuffer);
return ERR_COMMON_NO_MEMORY;
}
curl_easy_setopt(pstCurl, CURLOPT_HEADERFUNCTION,httpClient_WriteBack); /* 设置用于接收响应header的处理函数 */
curl_easy_setopt(pstCurl, CURLOPT_WRITEHEADER, &pstUserArg->stHttpUserHead); /* 接收头部分 */
}
curl_easy_setopt(pstCurl, CURLOPT_TIMEOUT, timeout); /* 设置接收超时时间,单位:秒 */
/* 5. 发送http请求 */
code = curl_easy_perform(pstCurl);
if(code != CURLE_OK)
{
printf("[CURL]http[%s] fail[%d:%s]\n", pstUserArg->szUrl, code, curl_easy_strerror(code));
FREE(pstUserArg->stHttpUserBody.pRcvBuffer);
FREE(pstUserArg->stHttpUserHead.pRcvBuffer);
curl_slist_free_all(pstHeaderlist);
pstHeaderlist = NULL;
curl_formfree(pstForm);
pstForm = NULL;
curl_easy_cleanup(pstCurl);
pstCurl = NULL;
return ERR_COMMON_FAIL;
}
/* 6. 获取http响应的错误码 */
curl_easy_getinfo(pstCurl, CURLINFO_RESPONSE_CODE, &response_code);
/* 7. 处理HTTP响应 */
if ((200 != response_code) && (201 != response_code))
{
printf("[CURL]curl_easy_getinfo RESPONSE_CODE: %ld(%s)\n", response_code, curl_easy_strerror(response_code));
nRet = ERR_COMMON_FAIL;
}
else
{
/* 自行添加http的处理回调 */
{
}
if (ERR_COMMON_SUCCEED != nRet)
{
printf("[CURL]proc Http Response fail[%d]\n", nRet);
}
}
/* 8. 释放资源 */
FREE(pstUserArg->stHttpUserBody.pRcvBuffer);
FREE(pstUserArg->stHttpUserHead.pRcvBuffer);
curl_slist_free_all(pstHeaderlist);
pstHeaderlist = NULL;
curl_formfree(pstForm);
pstForm = NULL;
curl_easy_cleanup(pstCurl);
pstCurl = NULL;
return nRet;
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。