您的位置:首页 > 运维架构

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;

}

上述代码都经过自己测试,如有什么问题,欢迎批评指正,非常的感谢~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: