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句柄的函数。
顶层是 InternetOpen函数,它创建根句柄。下一级包含 InternetOpenUrl和 InternetConnect功能。使用InternetConnect返回的句柄的函数 构成了最后一级。
下图显示了依赖于InternetOpenUrl创建的句柄的函数 。阴影框表示返回HINTERNET句柄的函数,而普通框表示使用由关联函数创建的HINTERNET句柄的函数。
下面只介绍了HTTP 层次
下图显示了用于HTTP协议的功能的关系。阴影框表示返回HINTERNET句柄的函数,而普通框表示使用由它们所依赖的函数创建的HINTERNET句柄的函数。
HttpAddRequestHeaders, HttpQueryInfo, HttpSendRequest中, HttpSendRequestEx,和 InternetErrorDlg函数功能取决于由创建的句柄 HttpOpenRequest中。
下图显示了在HttpOpenRequest返回HINTERNET句柄,给一系列函数使用。阴影框表示返回HINTERNET句柄的函数,而普通框表示使用由它们所依赖的函数创建的HINTERNET句柄的函数。
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;
}