Windows Internet - WinINet 学习笔记(1)

  1.关于WinINet
WinINet 不是给服务端用的,服务端用Microsoft Windows HTTP Services (WinHTTP)
WinINet 抽象了Gopher,FTP,HTTP协议的一些细节。
2.HINTERNET 句柄

WinINet函数创建、使用的句柄都是HINTERNET类型的,这种类型的句柄无法被转换成其它类型的句柄。换句话说,最好别用ReadFile、CloseHandle之类的函数来操作这些句柄。同样的,也别用WinINet函数来访问、操作其他类型的句柄。比如,用InternetReadFile访问CreateFile创建句柄是无法得到你想要的结果的。想关闭HINTERNET句柄要使用InternetCloseHandle函数。

3.句柄架构



InternetOpen 创建的句柄在顶层,由接下来的一层的 InternetOpenUrl 和 InternetConnect 使用,而 InternetConnect 创建的句柄又被之后的几个函数使用。

下面这张图是依赖 InternetOpenUrl 创建的句柄的几个函数,灰色的方框是返回 HINTERNET 句柄的函数,而白色的框就是使用被创建的HINTERNET 句柄的函数

Windows Internet - WinINet 学习笔记(1)_第1张图片

FTP Hierarchy




Windows Internet - WinINet 学习笔记(1)_第2张图片

HTTP Hierarchy




Windows Internet - WinINet 学习笔记(1)_第3张图片

注意这张图,这张图的意思是 HttpSendRequestEx 先访问 HttpOpenRequest 创建的句柄之后, HttpEndRequest,InternetReadFileEx 和 InternetWriteFile 才能访问这个句柄。 HttpEndRequest 被调用之后,才轮的到InternetReadFile,InternetSetFilePointer 和 InternetQueryDataAvailable 来访问这个句柄。

4.内容编码

HTTP 协议 (RFC 2616) 规定了应用程序可以要求服务器用编码的方式(encoded format)返回HTTP响应。在Windows Server 2008 与 Windows Vista之前,发送给应用程序的内容编码了的请求需要应用程序自己处理,从Windows Server 2008 and Windows Vista开始, 应用程序可以让 WinINet 来解码了(gzip与deflate)。有三种方式开启解码选项(基于会话、请求、连接),它们的作用域不同。可以使用InternetOpen(基于会话), InternetConnect(基于连接), HttpOpenRequest(基于请求)返回的句柄调用InternetSetOption 来打开或关闭解码选项,打开则将 dwOption 参数中INTERNET_OPTION_HTTP_DECODING 选项打开, 令 lpBuffer 指向一个为true的boolean变量. 关闭则dwOption 参数中INTERNET_OPTION_HTTP_DECODING 选项打开, 令 lpBuffer 指向一个为false的boolean变量 .

设置解码选项之后, WinInet 在你调用 InternetReadFile 是就会执行一次解码。不过就算你打开了解码选项,它也不一定就为你解码……当这种情况发生时, InternetReadFile 函数会失败并返回ERROR_INTERNET_DECODING_FAILED.这个时候你可以选择去掉Accept-Encoding头重新发送一次请求,或者把解码关掉然后自己来解码(这时你就得检查Content-Encoding头来判断编码方式了)。

5.协议无关函数

  • 从Internet下载文件 (InternetReadFileInternetSetFilePointerInternetFindNextFileInternetQueryDataAvailable).
  • 设置同步操作 (InternetSetStatusCallback).
  • 查询、修改设置 (InternetSetOption , InternetQueryOption).
  • 关闭 HINTERNET 句柄 (InternetCloseHandle).
  • 锁定、解锁资源文件 (InternetLockRequestFile , InternetUnlockRequestFile).
Function Description
InternetFindNextFile 继续文件的枚举或搜索. 需要以下函数创建的句柄 FtpFindFirstFileGopherFindFirstFileInternetOpenUrl
InternetLockRequestFile 允许用户锁定文件. 需要以下函数创建的句柄 FtpOpenFileGopherOpenFileHttpOpenRequestInternetOpenUrl .
InternetQueryDataAvailable 查询可用数据的数量. 需要以下函数创建的句柄 FtpOpenFileGopherOpenFileHttpOpenRequest .
InternetQueryOption 查询 Internet 设置.
InternetReadFile 读取 URL 数据. 需要以下函数创建的句柄 InternetOpenUrlFtpOpenFileGopherOpenFileHttpOpenRequest .
InternetSetFilePointer 设置文件指针. 需要以下函数创建的句柄 InternetOpenUrl ( HTTP URL only) HttpOpenRequest (GET 方法).
InternetSetOption 配置 Internet 设置.
InternetSetStatusCallback 设置一个接收状态信息的回调函数. 分配一个回调函数给指定的 HINTERNET 句柄及从其演化而来的句柄.
InternetUnlockRequestFile 解锁被 InternetLockRequestFile 锁定的文件.

读文件

函数 InternetReadFile 用来从一个由函数 InternetOpenUrlFtpOpenFileGopherOpenFileHttpOpenRequest 返回的HINTERNET 句柄下载资源.

WinINet 提供了两种方法来下载整个资源

  • InternetQueryDataAvailable 函数.
  • 利用 InternetReadFile 的返回值
  • InternetQueryDataAvailable 使用 InternetOpenUrlFtpOpenFileGopherOpenFileHttpOpenRequest (还记得上面的那个图么,这个函数需要在 HttpSendRequest 操作该句柄之后才能访问这个句柄) 创建的句柄。返回有效数据的字节数,据此,我们就可以分配足够的内存并进行读取,但是这种方法不保险,包头里的长度可能是过时的,而且包头也可能会丢。

    当所有数据都被读完的时候, InternetReadFile 会返回0字节被读取(lpdwNumberOfBytesRead 参数保存了读取的字节数). 据此,我们就可以循环调用 InternetReadFile 直到读取结束。

 

寻找文件

先使用 FtpFindFirstFileGopherFindFirstFile, 或 InternetOpenUrl ,然后将其返回的句柄作为参数 传递给InternetFindNextFile 进行继续查找,持续调用 InternetFindNextFile 知道返回扩展的错误信息 ERROR_NO_MORE_FILES 来完成整个搜索,调用 GetLastError 来获取最后的错误信息.

你可能感兴趣的:(Windows Internet - WinINet 学习笔记(1))