利用WinINet进行网络程序的编程

The Microsoft Windows Internet (WinINet)使应用程序使用标准Internet协议,例如FTP 和HTTP。WinINet抽象了这些协议成了一个个接口。需要注意的是WinINet只能用于客户端程序,而服务器端需要使用Microsoft Windows HTTP Services (WinHTTP)


关于HINTERNET 句柄

由WinINet函数创建和使用的句柄是HINTERNET类型。WinINet函数返回不能与其他句柄类型互换的HINTERNET句柄。因此,它们不能用于ReadFile或 CloseHandle等函数 。同样,其他句柄类型不能用于WinINet函数。例如,由CreateFile返回的句柄 无法传递给 InternetReadFile。

InternetCloseHandle函数关闭HINTERNET。请注意,句柄值会被快速回收; 因此,如果句柄关闭并且立即生成新句柄,则新句柄与刚刚关闭的句柄具有相同的值的可能性很大。

HINTERNET手柄保持在一个树状分层结构。InternetOpen函数返回的句柄 是根节点。由InternetConnect功能返回的句柄 占据了下一个级别。由FtpOpenFile, FtpFindFirstFile、HttpOpenRequest函数返回的句柄 是叶节点。

Windows XP和Windows Server 2003 R2及更早版本: 由GopherOpenFile和 GopherFindFirstFile返回的句柄 也是叶节点。

下图说明了HINTERNET句柄的层次结构。图中的每个框表示一个返回HINTERNET句柄的函数。

利用WinINet进行网络程序的编程_第1张图片

顶层是 InternetOpen函数,它创建根句柄。下一级包含 InternetOpenUrlInternetConnect功能。使用InternetConnect返回的句柄的函数 构成了最后一级。

下图显示了依赖于InternetOpenUrl创建的句柄的函数 。阴影框表示返回HINTERNET句柄的函数,而普通框表示使用由关联函数创建的HINTERNET句柄的函数。

利用WinINet进行网络程序的编程_第2张图片


下面只介绍了HTTP 层次

下图显示了用于HTTP协议的功能的关系。阴影框表示返回HINTERNET句柄的函数,而普通框表示使用由它们所依赖的函数创建的HINTERNET句柄的函数。

利用WinINet进行网络程序的编程_第3张图片

HttpAddRequestHeaders, HttpQueryInfo, HttpSendRequest中, HttpSendRequestEx,和 InternetErrorDlg函数功能取决于由创建的句柄 HttpOpenRequest中。

下图显示了在HttpOpenRequest返回HINTERNET句柄,给一系列函数使用。阴影框表示返回HINTERNET句柄的函数,而普通框表示使用由它们所依赖的函数创建的HINTERNET句柄的函数。

利用WinINet进行网络程序的编程_第4张图片

HTTP会话通过使用以下函数

函数 描述
HttpAddRequestHeaders 将HTTP请求标头添加到HTTP请求句柄。这个函数需要一个由HttpOpenRequest创建的句柄 。
HttpOpenRequest 打开一个HTTP请求句柄。此功能需要由InternetConnect创建的句柄 。
HttpQueryInfo 查询有关HTTP请求的信息。这个函数需要一个由HttpOpenRequest或 InternetOpenUrl函数创建的句柄 。
HttpSendRequest 将指定的HTTP请求发送到HTTP服务器。这个函数需要一个由HttpOpenRequest创建的句柄 。
InternetErrorDlg 显示常见Internet错误情况的预定义对话框。这个函数需要调用HttpSendRequest时使用的句柄 。
InternetOpen 初始化
InternetConnect 打开指定网站的HTTP会话

下面是示例

#include 
#include 
#pragma comment(lib, "wininet.lib")

int main()
{
    //http://movie.youku.com/?spm=a2hww.20027244.m_251424.5~1~3~8!2~A
    HINTERNET hInternetOpen = InternetOpen(_T("YouKu"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if (!hInternetOpen)
    {
        printf("InternetOpen error\n");
        goto END;
    }
    HINTERNET hSession = InternetConnect(hInternetOpen, _T("movie.youku.com"), INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
    if (!hSession)
    {
        printf("InternetConnect error\n");
        goto CLOSEINTERNETOPEN;
    }
    HINTERNET hRequest = HttpOpenRequest(hSession, _T("GET"), _T("/?spm=a2hww.20027244.m_251424.5~1~3~8!2~A"), NULL, NULL, 0, HTTP_ADDREQ_FLAG_ADD | INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_AUTO_REDIRECT | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES, 0);
    if (!hRequest)
    {
        printf("HttpOpenRequest error\n");
        goto CLOSECONNECTION;
    }
    if(!HttpAddRequestHeaders(hRequest, _T("Accept-Encoding: gzip"), -1, HTTP_ADDREQ_FLAG_REPLACE))
	    goto CLOSEREQUEST;
	    
    BOOL bRequest = HttpSendRequest(hRequest, NULL, 0, NULL, 0); //发送http请求
    char buff[1024] = { 0 };
    DWORD dw = 0;
    if (bRequest)
    {
        FILE *p = nullptr;
        fopen_s(&p, "D:\\CODE\\ConsoleApplication1\\Debug\\main.html", "w");
        while (true)
        {
            if (!InternetReadFile(hRequest, buff, 1024, &dw))
                break;

            if (!dw)
                break;

            fwrite(buff, sizeof(char), dw, p);
            ZeroMemory(buff, 1024);
        }
        fclose(p);
    }

    printf("over\n");
    
CLOSEREQUEST:
    InternetCloseHandle(hRequest);
CLOSECONNECTION:
    InternetCloseHandle(hSession);
CLOSEINTERNETOPEN:
    InternetCloseHandle(hInternetOpen);
END:
	getchar();
    return 0;
}

你可能感兴趣的:(网络编程,WinINet)