这篇文章以实例讲解如何使用HTTP常用的四种协议 put、post、get、delete,只要掌握一种,其他的在使用上都是大同小异。在实际项目开发过程中,这些工具会有帮助,HttpWatch或者Wireshark。最新的libcurl可以到http://curl.haxx.se/下载。关于资料可以参考官方文档。
库使用前准备工作:
引用lib库,并把文件夹curl复制到到工程项目目录中。代码部分如下:
#pragma comment (lib, "libcurl.lib" )
#pragma comment (lib, "libcurl_imp.lib" )
使用:
宏:
#define HTTPHEADER_CONTENTTYPE "Content-Type: application/json"
#define HTTPHEADER_ACCEPTLANGUAGE "Accept-Language: zh-cn"
#define HTTPHEADER_ACCEPT "Accept: application/json"
#define HTTPHEADER_TRANSFERENCODING "Transfer-Encoding:"
#define HTTPHEADER_EXPECT "Expect:"
#define HTTPHEADER_CONTENTLENGTH0 "Content-Length: 0"
回调函数:
size_t PutWriteFunCallBack(void *buffer, size_t size, size_t nmemb, void *stream)
{
//EnterCriticalSection(&m_csPutFunCallBack);
char *cRev = (char*)stream;
char *buf = (char*)buffer;
if (CString(buf).Find("{\"message\":") >= 0)
{
//strResponseJson = rev;
strcpy(cRev, buf);
}
size_t ret = size * nmemb;
//LeaveCriticalSection(&m_csPutFunCallBack);
return ret;
}
PUT
//=======================================================
// 函 数 名:DoHttpPut
// 功能描述:DoHttpPut
// 输入参数:strUrl:完整的路径,如登录接口
// http://10.166.46.169:8000/agentgateway/resource//onlineagent/104
// strBody:报文中的body,json格式,如:
/* "\r\n{\r\n\"password\":\"\",\r\n\"phonenum\":\"7106\",\r\n\"autoanswer\":\"true\"
,\r\n\"autoenteridle\":\"true\",\r\n\"releasephone\":\"true\",\r\n\"status\":4\r\n}"
*/
// 输出参数:
// 返回参数:
// 创建日期:2013.01.22
// 修改日期:2013.01.22
// 作 者:
// 附加说明:
//========================================================
CString CRESTFulBase::DoHttpPut(CString strUrl, CString strBody)
{
CString strRet("");
char cRev[LIBCURL_REVSIZE];
memset(cRev, 0, LIBCURL_REVSIZE);
CURL *m_curl = NULL;
m_curl = ::curl_easy_init();
if (NULL == m_curl)
{
return ERROR_LIBCURL;
}
//::curl_easy_reset(m_curl);
//要截取的字符串"http://10.166.46.169:8000/agentgateway/resource//onlineagent/106"
//strResponseJson = "";
CString strHostHeader = GetHostHeaderStr(strUrl);
int iBodyLen = strBody.GetLength();
CString strContentLenHeader("");
strContentLenHeader.Format("Content-Length: %d", iBodyLen);
::curl_easy_setopt(m_curl, CURLOPT_URL, strUrl);
::curl_easy_setopt(m_curl, CURLOPT_PUT, 1);
::curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, PutWriteFunCallBack);
::curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, cRev);
::curl_easy_setopt( m_curl, CURLOPT_TIMEOUT, m_iTimeOut);
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, HTTPHEADER_CONTENTTYPE);
headers = curl_slist_append(headers, HTTPHEADER_ACCEPTLANGUAGE);
headers = curl_slist_append(headers, strHostHeader);
headers = curl_slist_append(headers, HTTPHEADER_ACCEPT);
headers = curl_slist_append(headers, HTTPHEADER_TRANSFERENCODING);
headers = curl_slist_append(headers, strContentLenHeader);
headers = curl_slist_append(headers, HTTPHEADER_EXPECT);
headers = curl_slist_append(headers, strBody);
::curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(m_curl);
::curl_easy_cleanup(m_curl);
if(0 == strlen(cRev))
{
strRet = ERROR_LIBCURL;
}
else
{
strRet = GetJson(cRev);
}
return strRet;
}
POST
CString CRESTFulBase::DoHttpPost(CString strUrl, CString strBody)
{
CString strRet("");
char cRev[LIBCURL_REVSIZE];
memset(cRev, 0, LIBCURL_REVSIZE);
CURL *m_curl = NULL;
m_curl = ::curl_easy_init();
if (NULL == m_curl)
{
return ERROR_LIBCURL;
}
//要截取的字符串"http://10.166.46.169:8000/agentgateway/resource//onlineagent/106"
//strResponseJson = "";
CString strHostHeader = GetHostHeaderStr(strUrl);
int iBodyLen = strBody.GetLength();
CString strContentLenHeader("");
strContentLenHeader.Format("Content-Length: %d", iBodyLen);
::curl_easy_setopt(m_curl, CURLOPT_URL, strUrl);
::curl_easy_setopt(m_curl, CURLOPT_POST, 1);
::curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, PutWriteFunCallBack);
::curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, cRev);
::curl_easy_setopt( m_curl, CURLOPT_TIMEOUT, m_iTimeOut);
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, HTTPHEADER_CONTENTTYPE);
headers = curl_slist_append(headers, HTTPHEADER_ACCEPTLANGUAGE);
headers = curl_slist_append(headers, strHostHeader);
headers = curl_slist_append(headers, HTTPHEADER_ACCEPT);
headers = curl_slist_append(headers, HTTPHEADER_TRANSFERENCODING);
headers = curl_slist_append(headers, strContentLenHeader);
headers = curl_slist_append(headers, HTTPHEADER_EXPECT);
headers = curl_slist_append(headers, strBody);
::curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(m_curl);
::curl_easy_cleanup(m_curl);
if(0 == strlen(cRev))
{
strRet = ERROR_LIBCURL;
}
else
{
strRet = GetJson(cRev);
}
return strRet;
}
GET
//=======================================================
// 函 数 名:DoHttpGet
// 功能描述:DoHttpGet
// 输入参数:strUrl:完整的路径,如强制签出接口
// "http://10.166.46.169:8000/agentgateway/resource//onlineagent/104/forcelogout"
// iFlag:0,普通请求;1,轮询接口事件
// 输出参数:
// 返回参数:
// 创建日期:
// 修改日期:
// 作 者:
// 附加说明:
//========================================================
CString CRESTFulBase::DoHttpGet(CString strUrl, int iFlag)
{
EnterCriticalSection(&m_csHttpGet);
CString strRet("");
char cRev[LIBCURL_REVSIZE];
memset(cRev, 0, LIBCURL_REVSIZE);
CURL *m_curl = NULL;
m_curl = ::curl_easy_init();
if (NULL == m_curl)
{
return ERROR_LIBCURL;
}
//::curl_easy_reset(m_curl);
//要截取的字符串"http://10.166.46.169:8000/agentgateway/resource//onlineagent/106"
//strResponseJson = "";
CString strHostHeader = GetHostHeaderStr(strUrl);
::curl_easy_setopt(m_curl, CURLOPT_URL, strUrl);
::curl_easy_setopt(m_curl, CURLOPT_HTTPGET, 1);
::curl_easy_setopt(m_curl, CURLOPT_TIMEOUT, m_iTimeOut);
if(0 == iFlag)
{
::curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, PutWriteFunCallBack);
::curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, cRev);
}
else if(1 == iFlag)
{
CLog log;
log.WriteLog(0, "%s", "DoHttpGet");
::curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, EventWriteFunCallBack);
::curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, cRev);
}
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, HTTPHEADER_CONTENTTYPE);
headers = curl_slist_append(headers, HTTPHEADER_ACCEPTLANGUAGE);
headers = curl_slist_append(headers, strHostHeader);
headers = curl_slist_append(headers, HTTPHEADER_ACCEPT);
headers = curl_slist_append(headers, HTTPHEADER_TRANSFERENCODING);
headers = curl_slist_append(headers, HTTPHEADER_CONTENTLENGTH0);
headers = curl_slist_append(headers, HTTPHEADER_EXPECT);
::curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(m_curl);
::curl_easy_cleanup(m_curl);
if(0 == strlen(cRev))
{
strRet = ERROR_LIBCURL;
}
else
{
strRet = GetJson(cRev);
//有事件从服务器返回。
if (strRet.Find("\"event\":{") > 0)
{
DispatchEventMsg(strRet);
}
}
return strRet;
LeaveCriticalSection(&m_csHttpGet);
}
DELETE
//=======================================================
// 函 数 名:DoHttpDelete
// 功能描述:DoHttpDelete
// 输入参数:strUrl:完整的路径,如强制签出接口
// "http://10.166.46.169:8000/agentgateway/resource//onlineagent/104/forcelogout"
// 输出参数:
// 返回参数:
// 创建日期:2013.01.24
// 修改日期:2013.01.24
// 作 者:
// 附加说明:
//========================================================
CString CRESTFulBase::DoHttpDelete(CString strUrl)
{
CString strRet("");
char cRev[LIBCURL_REVSIZE];
memset(cRev, 0, LIBCURL_REVSIZE);
CURL *m_curl = NULL;
m_curl = ::curl_easy_init();
if (NULL == m_curl)
{
return ERROR_LIBCURL;
}
//::curl_easy_reset(m_curl);
//要截取的字符串"http://10.166.46.169:8000/agentgateway/resource//onlineagent/106"
//http://10.166.46.169:8000/agentgateway/resource//onlineagent/104/forcelogout
//strResponseJson = "";
CString strHostHeader = GetHostHeaderStr(strUrl);
::curl_easy_setopt(m_curl, CURLOPT_URL, strUrl);
::curl_easy_setopt(m_curl, CURLOPT_CUSTOMREQUEST, "DELETE");
::curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, PutWriteFunCallBack);
::curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, cRev);
::curl_easy_setopt( m_curl, CURLOPT_TIMEOUT, m_iTimeOut);
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, HTTPHEADER_CONTENTTYPE);
headers = curl_slist_append(headers, HTTPHEADER_ACCEPTLANGUAGE);
headers = curl_slist_append(headers, strHostHeader);
headers = curl_slist_append(headers, HTTPHEADER_ACCEPT);
headers = curl_slist_append(headers, HTTPHEADER_TRANSFERENCODING);
headers = curl_slist_append(headers, HTTPHEADER_CONTENTLENGTH0);
headers = curl_slist_append(headers, HTTPHEADER_EXPECT);
::curl_easy_setopt(m_curl, CURLOPT_HTTPHEADER, headers);
CURLcode ret = curl_easy_perform(m_curl);
::curl_easy_cleanup(m_curl);
if(0 == strlen(cRev))
{
strRet = ERROR_LIBCURL;
}
else
{
strRet = GetJson(cRev);
}
return strRet;
}
下载
//=======================================================
// 函 数 名:GetEmailAttach
// 功能描述:获取邮件附件
// 输入参数:cFileID: 文件ID
// 输出参数:
// 返回参数:
// 创建日期:2012.06.28
// 修改日期:2012.08.03
// 作 者:
// 附加说明:
//========================================================
int CDispatch::GetEmailAttach(char* cFileID, char* cFileName)
{
//参数校验
if (NULL == cFileID || strlen(cFileID) <= 0 || strlen(cFileID) > MAX_OCX_PARAM_LEN
|| NULL == cFileName || strlen(cFileName) <= 0 || strlen(cFileName) > MAX_OCX_PARAM_LEN)
{
m_strLastError = "";
m_strLastErrorMsg = "";
return ERROR_PARAM_ERROR;
}
//未签入
if (!m_bAgentLogin)
{
m_strLastError = "";
m_strLastErrorMsg = "";
return ERROR_NOT_SIGNIN;
}
BOOL bRet = FALSE;
int nRet = ERROR_OK;
//创建curl对象
CURL *curl;
CURLcode res;
struct HttpFile httpFile =
{
cFileName,
NULL
};
curl_global_init(CURL_GLOBAL_DEFAULT);
//curl初始化
curl = curl_easy_init();
//curl对象存在的情况下执行操作
if (curl)
{
//拼接地址
CString strURL;
strURL.Format(AGENT_REST_GETEMAILATTACH_URL, m_strAgentID);
strURL = m_strUrl + strURL + CString(cFileID);
//设置远端地址
curl_easy_setopt(curl, CURLOPT_URL, strURL);
//执行写入文件流操作
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &httpFile);
//写入文件
res = curl_easy_perform(curl);
//释放curl对象
curl_easy_cleanup(curl);
if (CURLE_OK != res)
{
nRet = ERROR_HTTP_FAIL;
}
}
if (httpFile.stream)
{
//关闭文件流
fclose(httpFile.stream);
}
//释放curl对象
curl_global_cleanup();
return nRet;
}
回调函数:
//=======================================================
// 函 数 名:my_fwrite
// 功能描述:回调函数,用于下载文件
// 输入参数:cURL: Agent服务器IP
// cService: Agent服务工程名
// 输出参数:
// 返回参数:
// 创建日期:
// 修改日期:
// 作 者:
// 附加说明:
//========================================================
int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
struct HttpFile *out=(struct HttpFile *)stream;
if (out && !out->stream)
{
out->stream = fopen(out->filename, "wb");
if (!out->stream)
{
return -1;
}
}
return fwrite(buffer, size, nmemb, out->stream);
}
发送
//=======================================================
// 函 数 名:SendEmailAttach
// 功能描述:座席在收到邮件类型的文字交谈后,调用下面的接口可以实现对邮件的回复。
// 输入参数:cCallID: //文字交谈的会话ID
// cFileName //磁盘完整路径
// 输出参数:
// 返回参数:
// 创建日期:
// 修改日期:
// 作 者:
// 附加说明:
//========================================================
int CDispatch::SendEmailAttach(char* cCallID, char* cFileName)
{
//参数校验
if (NULL == cCallID || strlen(cCallID) <= 0 || strlen(cCallID) > MAX_OCX_PARAM_LEN
|| NULL == cFileName || strlen(cFileName) <= 0 || strlen(cFileName) > MAX_OCX_PARAM_LEN)
{
m_strLastError = "";
m_strLastErrorMsg = "";
return ERROR_PARAM_ERROR;
}
//未签入
if (!m_bAgentLogin)
{
m_strLastError = "";
m_strLastErrorMsg = "";
return ERROR_NOT_SIGNIN;
}
int nRet = ERROR_OK;
//Rest请求的返回值
char cRecvMsg[MAX_REST_REQUEST_LEN + 1];
memset(cRecvMsg, 0, MAX_REST_REQUEST_LEN + 1);
//创建curl对象
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_WIN32);
//curl初始化
curl = curl_easy_init();
//curl对象存在的情况下执行操作
if (curl)
{
//拼接地址
CString strURL;
strURL.Format(AGENT_REST_SENDEMAILATTACH_URL, m_strAgentID);
strURL = m_strUrl + strURL + CString(cCallID);
//设置远端地址
curl_easy_setopt(curl, CURLOPT_URL, strURL);
curl_httppost *post = NULL;
curl_httppost *last = NULL;
// 文本数据
curl_formadd(&post, &last, CURLFORM_COPYNAME, "name", CURLFORM_COPYCONTENTS, "JGood", CURLFORM_END);
curl_formadd(&post, &last, CURLFORM_COPYNAME, "address", CURLFORM_COPYCONTENTS, "HangZhou", CURLFORM_END);
// 文本文件中的数据
curl_formadd(&post, &last, CURLFORM_COPYNAME, "file", CURLFORM_FILECONTENT, "D:\\Sunset.jpg", CURLFORM_END);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, GetRetMessage);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, cRecvMsg);
//curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, head_data);
//curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY);
/* char szRetcode[MAX_RET_PARAM_LEN];
memset(szRetcode, 0, MAX_RET_PARAM_LEN);
size_t size;
CURLcode rtcode = curl_easy_recv(curl, szRetcode, MAX_RET_PARAM_LEN, &size);
if (CURLE_AGAIN == rtcode)
{
int i;
i = 1;
}*/
//写入文件
res = curl_easy_perform(curl);
curl_formfree(post);
//CURLcode rtcode = curl_easy_recv( CURL * curl , void * buffer , size_t buflen , size_t * n );
if (CURLE_OK != res)
{
nRet = ERROR_HTTP_FAIL;
}
}
//释放curl对象
curl_global_cleanup();
return nRet;
}
回调函数:
//文件写入流
int GetRetMessage(void *buffer, size_t size, size_t nmemb, void *stream)
{
char *msg=(char *)stream;
strcat(msg,(char*)buffer);
return 0;
}