在VS2010中通过WinHttp和Java搭建的Web平台通信时出现一个很怪异的问题:当我直接建立一个win32 console的工程时,进行通信没有问题,但当我把原来代码放在一个新建的头文件中时,然后将这个头文件添加入MFC工程,然后在所需要这个头文件的地方包含这个头文件,编译时出现了以下问题:
错误error C2371: “HTTP_VERSION_INFO”: 重定义;不同的基类型 c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winhttp.h ,错误error C2371: “HTTP_VERSION_INFO”: 重定义;不同的基类型 c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winhttp.h ,错误error C2371: “URL_COMPONENTS”: 重定义;不同的基类型 c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winhttp.h 160,错误error C2371: “HTTP_VERSION_INFO”: 重定义;不同的基类型 c:\program files (x86)\microsoft sdks\windows\v7.0a\include\winhttp.h
代码如下:
#include "stdafx.h"
#include <afx.h>
#define USE_WINHTTP //Comment this line to user wininet.
#ifdef USE_WINHTTP
#include <winhttp.h>
#pragma comment(lib, "winhttp.lib")
#else
#include <wininet.h>
#pragma comment(lib, "wininet.lib")
#endif
#include <vector>
#define BUF_SIZE (1024)
class CrackedUrl
{
int m_scheme;
CStringW m_host;
int m_port;
CStringW m_path;
public:
CrackedUrl(LPCWSTR url)
{
URL_COMPONENTS uc = { 0};
uc.dwStructSize = sizeof(uc);
const DWORD BUF_LEN = 256;
WCHAR host[BUF_LEN];
uc.lpszHostName = host;
uc.dwHostNameLength = BUF_LEN;
WCHAR path[BUF_LEN];
uc.lpszUrlPath = path;
uc.dwUrlPathLength = BUF_LEN;
WCHAR extra[BUF_LEN];
uc.lpszExtraInfo = extra;
uc.dwExtraInfoLength = BUF_LEN;
#ifdef USE_WINHTTP
if (!WinHttpCrackUrl(url, 0, ICU_ESCAPE, &uc)) {
printf("Error:WinHttpCrackUrl failed!\n");
}
#else
if (!InternetCrackUrl(url, 0, ICU_ESCAPE, &uc)) {
printf("Error:InternetCrackUrl failed!\n");
}
#endif
m_scheme = uc.nScheme;
m_host = host;
m_port = uc.nPort;
m_path = path;
}
int GetScheme() const
{
return m_scheme;
}
LPCWSTR GetHostName() const
{
return m_host;
}
int GetPort() const
{
return m_port;
}
LPCWSTR GetPath() const
{
return m_path;
}
static CStringA UrlEncode(const char* p)
{
if (p == 0)
return CStringA();
CStringA buf;
for (;;)
{
int ch = (BYTE) (*(p++));
if (ch == '\0')
break;
if (isalnum(ch) || ch == '_' || ch == '-' || ch == '.')
buf += (char)ch;
else if (ch == ' ')
buf += '+';
else
{
char c[16];
wsprintfA(c, "%%%02X", ch);
buf += c;
}
}
return buf;
}
};
HINTERNET OpenSession(LPCWSTR userAgent = 0)
{
#ifdef USE_WINHTTP
return WinHttpOpen(userAgent, NULL, NULL, NULL, NULL);;
#else
return InternetOpen(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
#endif
}
HINTERNET Connect(HINTERNET hSession, LPCWSTR serverAddr, int portNo)
{
#ifdef USE_WINHTTP
return WinHttpConnect(hSession, serverAddr, (INTERNET_PORT) portNo, 0);
#else
return InternetConnect(hSession, serverAddr, portNo, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
#endif
}
HINTERNET OpenRequest(HINTERNET hConnect, LPCWSTR verb, LPCWSTR objectName, int scheme)
{
DWORD flags = 0;
#ifdef USE_WINHTTP
if (scheme == INTERNET_SCHEME_HTTPS) {
flags |= WINHTTP_FLAG_SECURE;
}
return WinHttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags);
#else
if (scheme == INTERNET_SCHEME_HTTPS) {
flags |= INTERNET_FLAG_SECURE;
}
return HttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags, 0);
#endif
}
BOOL AddRequestHeaders(HINTERNET hRequest, LPCWSTR header)
{
SIZE_T len = lstrlenW(header);
#ifdef USE_WINHTTP
return WinHttpAddRequestHeaders(hRequest, header, DWORD(len), WINHTTP_ADDREQ_FLAG_ADD);
#else
return HttpAddRequestHeaders(hRequest, header, DWORD(len), HTTP_ADDREQ_FLAG_ADD);
#endif
}
BOOL SendRequest(HINTERNET hRequest, const void* body, DWORD size)
{
#ifdef USE_WINHTTP
return WinHttpSendRequest(hRequest, 0, 0, const_cast<void*>(body), size, size, 0);
#else
return HttpSendRequest(hRequest, 0, 0, const_cast<void*>(body), size);
#endif
}
BOOL EndRequest(HINTERNET hRequest)
{
#ifdef USE_WINHTTP
return WinHttpReceiveResponse(hRequest, 0);
#else
// if you use HttpSendRequestEx to send request then use HttpEndRequest in here!
return TRUE;
#endif
}
BOOL QueryInfo(HINTERNET hRequest, int queryId, char* szBuf, DWORD* pdwSize)
{
#ifdef USE_WINHTTP
return WinHttpQueryHeaders(hRequest, (DWORD) queryId, 0, szBuf, pdwSize, 0);
#else
return HttpQueryInfo(hRequest, queryId, szBuf, pdwSize, 0);
#endif
}
BOOL ReadData(HINTERNET hRequest, void* buffer, DWORD length, DWORD* cbRead)
{
#ifdef USE_WINHTTP
return WinHttpReadData(hRequest, buffer, length, cbRead);
#else
return InternetReadFile(hRequest, buffer, length, cbRead);
#endif
}
void CloseInternetHandle(HINTERNET hInternet)
{
if (hInternet)
{
#ifdef USE_WINHTTP
WinHttpCloseHandle(hInternet);
#else
InternetCloseHandle(hInternet);
#endif
}
}bool HttpQuest(const CString &strUrl,const CString &strHeader,const CString &strPost,CString &strReturn,BOOL bPost)
{
HINTERNET hSession = 0;
HINTERNET hConnect = 0;
HINTERNET hRequest = 0;
LPCWSTR Url=strUrl.AllocSysString();
// Test data
CrackedUrl crackedUrl(Url);
// Open session.
hSession = OpenSession(L"User Agent");
if (hSession == NULL)
{
printf("Error:Open session!\n");
return -1;
}
// Connect.
hConnect = Connect(hSession, crackedUrl.GetHostName(), crackedUrl.GetPort());
if (hConnect == NULL)
{
printf("Error:Connect failed!\n");
return -1;
}
// Open request.
LPCWSTR strPostOrGet;
if (bPost)
{
CString strTmp("POST");
strPostOrGet=strTmp.AllocSysString();
}
else
{
CString strTmp("GET");
strPostOrGet=strTmp.AllocSysString();
}
hRequest = OpenRequest(hConnect,strPostOrGet,crackedUrl.GetPath(), crackedUrl.GetScheme());
if (hRequest == NULL)
{
printf("Error:OpenRequest failed!\n");
return -1;
}
// Add request header.
LPCWSTR strHeaderW = strHeader.AllocSysString();
if (!AddRequestHeaders(hRequest, strHeaderW))
{
printf("Error:AddRequestHeaders failed!\n");
return -1;
}
// Send post data.
CStringA strPostData(strPost);
if (!SendRequest(hRequest, (const char*)strPostData, strPostData.GetLength()))
{
printf("Error:SendRequest failed!\n");
return -1;
}
// End request
if (!EndRequest(hRequest))
{
printf("Error:EndRequest failed!\n");
return -1;
}
char szBuf[BUF_SIZE];
DWORD dwSize = 0;
szBuf[0] = 0;
// Query header info.
#ifdef USE_WINHTTP
int contextLengthId = WINHTTP_QUERY_CONTENT_LENGTH;
int statusCodeId = WINHTTP_QUERY_STATUS_CODE;
int statusTextId = WINHTTP_QUERY_STATUS_TEXT;
#else
int contextLengthId = HTTP_QUERY_CONTENT_LENGTH;
int statusCodeId = HTTP_QUERY_STATUS_CODE;
int statusTextId = HTTP_QUERY_STATUS_TEXT;
#endif
dwSize = BUF_SIZE;
if (QueryInfo(hRequest, contextLengthId, szBuf, &dwSize))
{
szBuf[dwSize] = 0;
printf("Content length:[%s]\n", szBuf);
}
dwSize = BUF_SIZE;
if (QueryInfo(hRequest, statusCodeId, szBuf, &dwSize))
{
szBuf[dwSize] = 0;
printf("Status code:[%s]\n", szBuf);
}
dwSize = BUF_SIZE;
if (QueryInfo(hRequest, statusTextId, szBuf, &dwSize))
{
szBuf[dwSize] = 0;
printf("Status text:[%s]\n", szBuf);
}
// read data.
for (;;)
{
dwSize = BUF_SIZE;
if (ReadData(hRequest, szBuf, dwSize, &dwSize) == FALSE)
break;
if (dwSize <= 0)
break;
szBuf[dwSize] = 0;
printf("%s\n", szBuf);
strReturn=(CString)szBuf;
}
CloseInternetHandle(hRequest);
CloseInternetHandle(hConnect);
CloseInternetHandle(hSession);
}