/*
以前接触网络的时候,认为用户层用socket足矣(其实还有比socket更底层的),别的都不用,这样停止了几年.
后来发现有一些操作,还是用高级的好.
这就知道了.WinINet和WinHTTP等.
好像WinHTTP是WinINet的子集(IWinHttpRequest又是WinHTTP的子集),但比WinINet效率高,还可以用于服务器.
以前也知道点,但没有具体深入.
前几天算是开始了,费了一个多月的时间才把下面的小问题搞定.
下面的代码来自:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa384104(v=vs.85).aspx
等.
并加一些注释.没有精简.
再说一下:
看似简单的几个函数,如果不深刻理解总是出错的.
原因在于示例程序可以运行,修改别的就不行了.
注意参数的设置:如端口,协议等.一定要配合.
下面的代码经过简单的修改,可以成功的访问:
www.microsoft.com
www.baidu.com
www.google.com.hk 注释:访问www.google.com,得到的数据不是我们想要的,可能又转到了:www.google.com.hk
www.126.com
*/
#include <windows.h>
#include <Winhttp.h>
#pragma comment(lib, "Winhttp.lib")
void wmain(void)
{
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen( L"WinHTTP Example/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, //WINHTTP_ACCESS_TYPE_NO_PROXY WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
WINHTTP_NO_PROXY_NAME, //#define WINHTTP_NO_PROXY_NAME NULL
WINHTTP_NO_PROXY_BYPASS, 0);//#define WINHTTP_NO_PROXY_BYPASS NULL
// Specify an HTTP server.
if (hSession)
{
DWORD data;
DWORD dwSize = sizeof(DWORD);
WinHttpSetTimeouts( hSession, 60000000, 60000000, 60000000, 60000000);//我这台电脑上的原始值是:60000ms,设置大点,防止因为这个而出现错误.
// Use WinHttpQueryOption to retrieve internet options.
if (WinHttpQueryOption( hSession,
WINHTTP_OPTION_CONNECT_TIMEOUT,
&data, &dwSize))
{
printf("Connection timeout: %u ms\n\n",data); //60000ms
}
else
{
printf( "Error %u in WinHttpQueryOption.\n",
GetLastError());
}
// When finished, release the HINTERNET handle.
// WinHttpCloseHandle(hSession);
//以上这几行代码也摘抄自msdn .
hConnect = WinHttpConnect( hSession, L"correy.webs.com", //www.microsoft.com www.baidu.com www.google.com.hk 支持L"220.181.112.143"格式.不要加http://和https://
INTERNET_DEFAULT_HTTP_PORT, 0); //INTERNET_DEFAULT_HTTP_PORT INTERNET_DEFAULT_HTTPS_PORT //设置端口,注意要和协议匹配.
}
// Create an HTTP request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL,//可以改为"POST","HEAD".等.
NULL, //Pointer to a string that contains the HTTP version. If this parameter is NULL, the function uses HTTP/1.1.
WINHTTP_NO_REFERER, //还可以写具体的相对位置.如果没有,可以设置为WINHTTP_NO_REFERER
WINHTTP_DEFAULT_ACCEPT_TYPES, //see Media Types defined by IANA at http://www.iana.org/assignments/media-types/.
WINHTTP_FLAG_REFRESH);//WINHTTP_FLAG_REFRESH WINHTTP_FLAG_SECURE 设置协议, 注意要和端口匹配.
// Send a request.
if (hRequest)
bResults = WinHttpSendRequest( hRequest,//这个很费时间.
WINHTTP_NO_ADDITIONAL_HEADERS,
0, WINHTTP_NO_REQUEST_DATA, 0,
0, 0); //用GetLastError返回的错误码,结合函数说明在头文件里面查,msdn上也有的.
int x = ERROR_WINHTTP_CANNOT_CONNECT; //goto definition用的.
//具体的查看信息是:http://msdn.microsoft.com/en-us/library/windows/desktop/aa383770(v=vs.85).aspx
// End the request.
if (bResults)
bResults = WinHttpReceiveResponse( hRequest, NULL); //ERROR_WINHTTP_CANNOT_CONNECT
// Keep checking for data until there is nothing left.
if (bResults)
{
do
{
// Check for available data.
dwSize = 0;
if (!WinHttpQueryDataAvailable( hRequest, &dwSize))
{
printf( "Error %u in WinHttpQueryDataAvailable.\n",
GetLastError());
break;
}
// No more available data.
if (!dwSize)
break;
// Allocate space for the buffer.
pszOutBuffer = new char[dwSize+1];
if (!pszOutBuffer)
{
printf("Out of memory\n");
break;
}
// Read the Data.
ZeroMemory(pszOutBuffer, dwSize+1);
if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer,
dwSize, &dwDownloaded))
{
printf( "Error %u in WinHttpReadData.\n", GetLastError());
}
else
{
printf("%s", pszOutBuffer);
}
// Free the memory allocated to the buffer.
delete [] pszOutBuffer;
// This condition should never be reached since WinHttpQueryDataAvailable
// reported that there are bits to read.
if (!dwDownloaded)
break;
} while (dwSize > 0);
}
else
{
// Report any errors.
printf( "Error %d has occurred.\n", GetLastError() );
}
// Close any open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
}
//made by correy
没有评论:
发表评论