Windows API OpenURL无法设置超时时间替换方法
2015-06-27 21:19
423 查看
问题背景:
在VC++下面开发访问HTTP页面,最简单的方法莫过于下面这样的调用方式,这样写完程序测试OK,但是上线运行一段时间,程序时不时给你弹出一个什么错误,点击确定之后程序异常退出,这是为什么呢,仔细查看这一段代码,我们可以看出代码中没有设定HTTP访问超时的时间,问题可能就出在这,因为我将程序这段代码屏蔽掉运行没有问题。
因此我在网上查找相关信息,大部分人说Windows这个OpenURL函数就不能设定时间,迫于无奈我信了,只能想其他解决办法,这时找到了CURL开源代码,据说伟大的苹果也在使用这个开源代码,于是决定修改代码使用CURL,详情请见第二部分具体解决办法:
[cpp] view plaincopyprint?
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] view plaincopyprint?
#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] view plaincopyprint?
#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] view plaincopyprint?
#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;
}
上述代码都经过自己测试,如有什么问题,欢迎批评指正,非常的感谢~~
在VC++下面开发访问HTTP页面,最简单的方法莫过于下面这样的调用方式,这样写完程序测试OK,但是上线运行一段时间,程序时不时给你弹出一个什么错误,点击确定之后程序异常退出,这是为什么呢,仔细查看这一段代码,我们可以看出代码中没有设定HTTP访问超时的时间,问题可能就出在这,因为我将程序这段代码屏蔽掉运行没有问题。
因此我在网上查找相关信息,大部分人说Windows这个OpenURL函数就不能设定时间,迫于无奈我信了,只能想其他解决办法,这时找到了CURL开源代码,据说伟大的苹果也在使用这个开源代码,于是决定修改代码使用CURL,详情请见第二部分具体解决办法:
[cpp] view plaincopyprint?
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] view plaincopyprint?
#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] view plaincopyprint?
#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] view plaincopyprint?
#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;
}
上述代码都经过自己测试,如有什么问题,欢迎批评指正,非常的感谢~~
相关文章推荐
- Linux远程连接putty出现Network Erroe: Software caused connection abort
- Euclid's GCD Algorithm——MIT Open Courseware(Computability)
- linux命令
- apache+php+mysql环境配置
- 容器+AOP实现动态部署(四)
- 11个超棒的iOS开发学习网站
- Sqoop处理Clob与Blob字段
- openlayers3 在地图上叠加WFS查询矢量图层
- linux 环境变量设置方法总结(PATH/LD_LIBRARY_PATH)
- 不能再docker容器中使用宿主机的docker服务的解决方案
- Openlayers3 计算地图上任意两点间的距离
- 容器+AOP实现动态部署(三)
- 虚拟机Linux----Ubuntu1204----安装jdk1.8
- linux常用命令的英文单词缩写
- Linux图形界面与字符界面切换
- Hadoop优化 第一篇 : HDFS/MapReduce
- J2EE编辑中的中文乱码解决问题
- [Linux]在终端启动程序关闭终端不退出的方法
- 通过在shell脚本中用scp或rsync实现远程同步文件
- Bash中单引号和双引号的区别