2012年7月5日星期四

WinHttpReadData.Cpp


/*
以前接触网络的时候,认为用户层用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

没有评论:

发表评论