问题背景:
在VC++下面开发访问HTTP页面,最简单的方法莫过于下面这样的调用方式,这样写完程序测试OK,但是上线运行一段时间,程序时不时给你弹出一个什么错误,点击确定之后程序异常退出,这是为什么呢,仔细查看这一段代码,我们可以看出代码中没有设定HTTP访问超时的时间,问题可能就出在这,因为我将程序这段代码屏蔽掉运行没有问题。
因此我在网上查找相关信息,大部分人说Windows这个OpenURL函数就不能设定时间,迫于无奈我信了,只能想其他解决办法,这时找到了CURL开源代码,据说伟大的苹果也在使用这个开源代码,于是决定修改代码使用CURL,详情请见第二部分具体解决办法:
[cpp]
char* headers="Accept:*/*\r\nAccept-Language:zh-cn\r\nContent-type:text/html;charset=ANSI\r\nUser-Agent:ImportFileClient\r\n";
CHttpFile * pFile = (CHttpFile *)m_pInternetSession->OpenURL(strURL, 1, INTERNET_FLAG_TRANSFER_ASCII||INTERNET_FLAG_RELOAD, headers, strlen(headers));
DWORD dwStatusCode;
pFile->QueryInfoStatusCode(dwStatusCode);
if (dwStatusCode == HTTP_STATUS_OK)
{
CFile file(strSavePath, CFile::modeCreate | CFile::modeWrite);
CString szData;//, szAllData;
while (pFile->ReadString(szData))
{
//把读取来的utf-8转成ansi
int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szData, szData.GetLength(), NULL, 0);
wchar_t * wszString = new wchar_t[wcsLen+1];
::MultiByteToWideChar(CP_UTF8, NULL, szData, szData.GetLength(), wszString, wcsLen);
wszString[wcsLen] = '\0';
int ansiLen = ::WideCharToMultiByte(CP_ACP, NULL, wszString, wcsLen, NULL, 0, NULL, NULL);
char * szAnsi = new char[ansiLen + 1];
::WideCharToMultiByte(CP_ACP, NULL, wszString, wcsLen, szAnsi, ansiLen, NULL, NULL);
szAnsi[ansiLen] = '\0';
//写进文件
file.Write(szAnsi, ansiLen * sizeof(char));
delete wszString;
delete szAnsi;
}
pFile->Close();
file.Close();
}
具体解决办法:
CURL环境部署及简单测试可以参考:http://blog.csdn.net/heavenopener/article/details/5424857
由于上面的例子仍然设置访问超时时间,因此代码需要重新修改一下,我重新封装一个头文件及对应的CPP文件,具体请见第三部分——部分源代码
调用例子:
[cpp]
#include "UrlPlus.h"
int main(int argc, char* argv[])
{
CString strRet = get("http://202.102.92.68:8000/db.aspx?protype=user_status_json&h=18929552551");
printf("%s",strRet.GetBuffer(0));
return 0;
}
部分源码:
UrlPlus.h
[cpp]
#include <stdio.h>
#include <afx.h>
#include <curl/curl.h>
#include <curl/easy.h>
#pragma comment(lib, "curllib.lib")
extern char szbuffer[10240];
extern char szErrorBuffer[CURL_ERROR_SIZE];
int DownloadData(char *data, size_t size, size_t nmemb, char *writerData);
CString get(CString strURL);
CString post(CString strURL, CString strContent);
UrlPlus.cpp
[cpp]
#include "StdAfx.h"
#include "UrlPlus.h"
char szbuffer[10240];
char szErrorBuffer[CURL_ERROR_SIZE];
int DownloadData(char *data, size_t size, size_t nmemb, char *writerData)
{
if (writerData == NULL)
{
return 0;
}
int len = size*nmemb;
strcat(writerData,data);
return len;
}
CString get(CString strURL)
{
memset(szbuffer,0x0,sizeof(szbuffer));
CURL *pCurl = NULL;
pCurl = curl_easy_init();
if(pCurl == NULL)
{
//Print Error Info
}
curl_easy_setopt(pCurl, CURLOPT_ERRORBUFFER, szErrorBuffer);
curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 300);
curl_easy_setopt(pCurl, CURLOPT_URL, strURL.GetBuffer(0));
curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, &DownloadData);
curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, szbuffer);
curl_easy_setopt(pCurl, CURLOPT_HEADER, 0);
CURLcode code = curl_easy_perform(pCurl);
if(code != CURLE_OK)
{
//curl_easy_perform failed
}
if (pCurl)
{
curl_easy_cleanup(pCurl);
pCurl = NULL;
}
return szbuffer;
}
CString post(CString strURL, CString strContent)
{
memset(szbuffer,0x0,sizeof(szbuffer));
CURL *pCurl = NULL;
pCurl = curl_easy_init();
if(pCurl == NULL)
{
//Print Error Info
}
curl_easy_setopt(pCurl, CURLOPT_ERRORBUFFER, szErrorBuffer);
curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 300);
curl_easy_setopt(pCurl, CURLOPT_URL, strURL.GetBuffer(0));
curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, &DownloadData);
curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, szbuffer);
curl_easy_setopt(pCurl, CURLOPT_HEADER, 0);
curl_easy_setopt(pCurl, CURLOPT_POST, 1 );
curl_easy_setopt(pCurl, CURLOPT_POSTFIELDS, strContent.GetBuffer(0));
CURLcode code = curl_easy_perform(pCurl);
if(code != CURLE_OK)
{
//curl_easy_perform failed
}
if (pCurl)
{
curl_easy_cleanup(pCurl);
pCurl = NULL;
}
return szbuffer;
}
上述代码都经过自己测试,如有什么问题,欢迎批评指正,非常的感谢~~