这一日,我祭起WinInet类下载CSDN的XML文件,遇到了个莫名其妙的问题……
现将问题和解决办法粘贴于此,如果你遇到类似问题大可用类似方法尝试解决。
其中实现GET请求的代码如下:
void CInternet::Get(CString &csResponse,//返回的内容
const char *szServer,//服务器
INTERNET_PORT& nPort,//端口
const char* szObject,//URI
DWORD& dwHttpStatus)//结果
{
CInternetSession* pSession = NULL;
CHttpConnection* pConnection = NULL;
CHttpFile* pHttpFile = NULL;
try
{
pSession = new CInternetSession(
NULL,
1,
INTERNET_OPEN_TYPE_PRECONFIG);
pConnection = pSession->GetHttpConnection(szServer,
nPort,
NULL,
NULL);
pHttpFile = pConnection->OpenRequest(
NULL,//msdn 说 :"If NULL, ‘GET’ is used. "
szObject,
szServer,
1,
NULL,
NULL,
INTERNET_FLAG_EXISTING_CONNECT);
pHttpFile->SendRequest();
if (pHttpFile)
{
if (pHttpFile->QueryInfoStatusCode(dwHttpStatus)!=0)//程序在这出现异常
{
if (dwHttpStatus < 400)
{
int nRead = 0;
LPSTR pBuffer = new char[1024];
do
{
nRead = pHttpFile->Read(pBuffer, 1023);
if (nRead != 0)
{
pBuffer[nRead] = 0;
csResponse += pBuffer;
}
} while (nRead != 0);
if(pBuffer)
{
delete pBuffer;
pBuffer = NULL;
}
}
}
}
}
catch (CInternetException* e)
{
e->Delete();
}
catch (...)
{
}
if (pHttpFile != NULL)
{
pHttpFile->Close();
delete pHttpFile;
}
if (pConnection != NULL)
{
pConnection->Close();
delete pConnection;
}
if (pSession != NULL)
{
pSession->Close();
delete pSession;
}
}
接下来,我对该函数进行测试的时候遇到非常非常FAINT的问题,程序在QueryInfoStatusCode处出现异常终止。
测试代码如下:
CInternet internet;
CString csResponse;
DWORD dw;
INTERNET_PORT port = 80;
internet.Get(csResponse,"www.csdn.net",port,"/expert/topic/530/530120.xml",dw);
翻遍了MSDN也没找到原因,无奈之即想起了sniffer pro.
遂用其将HTTP包截获,惊现以下报文:
POST /expert/topic/530/530120.xml HTTP/1.1
Referer: www.csdn.net
If-Modified-Since: Tue, 26 Feb 2002 01:12:00 GMT
If-None-Match: "46f3959762bec11:92f"
User-Agent: csdnPoster
Host: www.csdn.net
Content-Length: 0
Cache-Control: no-cache
Cookie: aaa48=http%3A%2F%2Fwww%2Ecsdn%2Enet%2F
从包的第一行我们发现,WinInet私自把我们请求的方法变成了POST!!!
CHttpConnection::OpenRequest
CHttpFile* OpenRequest( LPCTSTR pstrVerb, LPCTSTR pstrObjectName, LPCTSTR pstrReferer = NULL, DWORD dwContext = 1, LPCTSTR* pstrAcceptTypes = NULL, LPCTSTR pstrVersion = NULL, DWORD dwFlags = INTERNET_FLAG_EXISTING_CONNECT );
Parameters
pstrVerb
A pointer to a string containing the verb to use in the request. If NULL, "GET" is used.
注意红色的那段解释,那么我在上文代码中使用
pHttpFile = pConnection->OpenRequest(
NULL,//msdn 说 :"If NULL, ‘GET’ is used. "
szObject,
szServer,
1,
NULL,
NULL,
INTERNET_FLAG_EXISTING_CONNECT);
是完全可行的。但结果却正好相反。
最终呢,我将上面OpenRequest的第一个参数改为"GET",问题解决了。