WinHTTP 中的 HINTERNET 句柄

Microsoft Windows HTTP Services (WinHTTP) 使用句柄跟踪使用 HTTP 协议时所需的设置和信息。 每个句柄都维护与 HTTP 会话、与 HTTP 服务器的连接或特定资源相关的信息。 本主题介绍各种类型的句柄、这些句柄的命名约定及其分层结构。

关于 HINTERNET 句柄

WinHTTP 创建并使用的句柄称为 HINTERNET 句柄。 WinHTTP 函数返回不可与其他句柄互换的 HINTERNET 句柄,因此它们不能与 ReadFileCloseHandle 等函数一起使用。 同样,其他句柄不能与 WinHTTP 函数一起使用。 例如, CreateFile 返回的句柄无法传递到 WinHttpReadData。 在使用句柄的 API 调用正在进行时,无法关闭这些 HINTERNET 句柄。 为了避免争用情况,应用程序应保护句柄,并防止它关闭,只要 API 调用正在进行。

Microsoft Win32 Internet (WinInet) 函数也使用 HINTERNET 句柄。 但是,WinInet 函数中使用的句柄不能与 WinHTTP 函数中使用的句柄互换。 有关 WinInet 的详细信息,请参阅 关于 WinINet

WinHttpCloseHandle 函数关闭 WinHTTP HINTERNET 句柄。

命名句柄

在整个 WinHTTP 文档中,应用程序编程接口 (API) 和示例代码中的函数的说明演示了各种类型的 HINTERNET 句柄的创建和使用。 为了跟踪不同类型的可用句柄,这些句柄的命名是一致的。 下表显示了文档中约定使用的标识符。

句柄类型 函数创建句柄 标识符
泛型句柄 WinHttpOpenWinHttpConnectWinHttpOpenRequest hInternet
会话句柄 WinHttpOpen hSession
连接句柄 WinHttpConnect hConnect
请求句柄 WinHttpOpenRequest hRequest
Web 套接字句柄 WinHttpWebSocketCompleteUpgrade hWebSocket

句柄层次结构

HINTERNET 句柄在层次结构中维护。 WinHttpOpen 返回的句柄是会话 HINTERNET 句柄。 调用 WinHttpOpen 可初始化 WinHTTP 函数并启动会话上下文,该上下文在会话句柄的整个生命周期内维护用户信息和设置。 WinHttpConnect 指定目标 HTTP 或 HTTPS 服务器,并创建连接 HINTERNET 句柄。 默认情况下,连接句柄继承会话句柄的设置。 通过调用 WinHttpOpenRequest 指定的每个资源都会分配一个请求 HINTERNET 句柄。

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

创建句柄的函数

关闭句柄后,应用程序必须准备好接收句柄上的回调通知,直到返回最终 WINHTTP_CALLBACK_STATUS_HANDLE_CLOSED 值,以指示句柄 (完全关闭,或者直到应用程序执行自己的等效同步,例如跟踪和等待挂起的异步操作的任何回调,并确保不再使用该句柄) 尝试进一步操作。

会话句柄称为用于创建的任何连接句柄的父级;同样,连接句柄及其父会话句柄都称为连接句柄用于创建的任何请求句柄的父级。

关闭父句柄时,即使父句柄本身未关闭,其任何子句柄也会间接失效,使用父句柄的后续请求会失败并 出现错误ERROR_INVALID_HANDLE。 无法依赖挂起的异步请求才能正确完成。

下图显示了使用 WinHttpOpenRequest 创建的 HINTERNET 句柄的函数。 带阴影的框表示创建句柄的 WinHTTP 函数,普通框显示使用这些 HINTERNET 句柄的函数。 此关系图还组织为显示通常调用 WinHTTP 函数的顺序。

创建句柄的函数

句柄层次结构的说明

首先,使用 WinHttpOpen 创建会话句柄。 WinHttpConnect 需要会话句柄作为其第一个参数,并返回指定服务器的连接句柄。 请求句柄由 WinHttpOpenRequest 创建,它使用 WinHttpConnect 创建的连接句柄。 如果应用程序选择向请求添加其他标头,或者应用程序需要设置身份验证凭据,则可以使用此请求句柄调用 WinHttpAddRequestHeadersWinHttpSetCredentials 。 请求由 WinHttpSendRequest 发送,后者使用请求句柄。 发送请求后,可以使用 WinHttpWriteData 将其他数据发送到服务器,或者应用程序可以直接跳到 WinHttpReceiveResponse ,以指定不向服务器发送更多信息。 此时,根据应用程序的用途,请求句柄可用于调用 WinHttpQueryHeadersWinHttpQueryAuthSchemes,或使用 WinHttpQueryDataAvailableWinHttpReadData 检索资源。

句柄层次结构中的 Web 套接字

Web 套接字句柄继承自连接和会话句柄,并在句柄层次结构中占据与请求句柄类似的位置。 若要创建 Web 套接字句柄,必须存在请求句柄;但创建 Web 套接字句柄后,请求可能会关闭,并且 Web 套接字句柄将继续正常运行。