这篇文章以实例讲解如何使用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; }
//======================================================= // 函 数 名: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; }
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; }
//======================================================= // 函 数 名: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); }
//======================================================= // 函 数 名: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; }