WinHTTP 会话概览

WinHTTP 会话概览WinHTTP会话概览TheMicrosoftWindowsHTTPServices(WinHTTP)exposesasetofC/C++functionsthatenableyourapplicationtoaccessHTTPresourcesontheWeb.Thistopicprovidesanoverviewofho

大家好,又见面了,我是你们的朋友全栈君。

WinHTTP 会话概览

The Microsoft Windows HTTP Services (WinHTTP) exposes a set of C/C++ functions that enable your application to access HTTP resources on the Web. This topic provides an overview of how these functions are used to interact with an HTTP server.

微软的HTTP服务(WinHTTP)暴露了一些C++函数,这些函数能让你的程序访问Web网络上的HTTP资源。这篇文章告诉你怎么使用这些函数和HTTP服务器进行交互。

使用 WinHTTP API 访问 Web

The following diagram shows the order in which WinHTTP functions are typically called when interacting with an HTTP server. The shaded boxes represent functions that generate anHINTERNET handle, while the plain boxes represent functions that use those handles.

下面的流程图显示了和HTTP服务器使用WinHTTP函数的典型应用。带阴影的框表示这些函数会产生HINTERNET句柄,白框中的函数会用到这些句柄。

Functions that create handles

初始化 WinHTTP

Before interacting with a server, WinHTTP must be initialized by calling WinHttpOpen. WinHttpOpen creates a session context to maintain details about the HTTP session, and returns a session handle.Using this handle, theWinHttpConnect function is then able to specify a target HTTP or Secure Hypertext Transfer Protocol (HTTPS) server.

开始和服务器交互前,WinHTTP必须使用WinHttpOpen进行初始化,WinHttpOpen会创建一个会话Context,这个会话Context包含了HTTP会话的细节,并且把这个会话Context的句柄返回。使用这个句柄,WinHttpConnect函数就可以指定一个目标HTTP或HTTPS服务器。

Note  A call to
WinHttpConnect does not result in an actual connection to the HTTP server until a request is made for a specific resource.

注意 对
WinHttpConnect的调用不会立即产生与HTTP服务器的连接请求,连接请求实在请求具体的资源时产生的。

打开一个请求

The WinHttpOpenRequest function opens an HTTP request for a particular resource and returns anHINTERNET handle that can be used by the other HTTP functions. WinHttpOpenRequest does not send the request to the server when called. TheWinHttpSendRequest function actually establishes a connection over the network and sends the request.

WinHttpOpenRequest函数为特定的资源打开一个HTTP请求,然后返回一个HINTERNET句柄,这个句柄可以被其他HTTP函数使用。WinHttpOpenRequest也不会向服务器发送数据。WinHttpSendRequest函数才会与服务器建立连接并发送请求。

The following example shows a sample call to WinHttpOpenRequest that uses the default options.

下面是使用默认参数调用WinHttpOpenRequest的例子。

HINTERNET hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, NULL, NULL, 0);

添加请求头部

The WinHttpAddRequestHeaders function allows an application to append additional free-format request headers to the HTTP request handle. It is intended for use by sophisticated applications that require precise control over the requests sent to the HTTP server.

WinHttpAddRequestHeaders函数允许应用程序向HTTP请求中添加各种格式的头部信息。这样让客户端与服务器实现复杂应用与精细控制。

The WinHttpAddRequestHeaders function requires an HTTP request handle created byWinHttpOpenRequest, a string that contains the headers, the length of the headers, and any modifiers.

WinHttpAddRequestHeaders函数需要一个WinHttpOpenRequest产生的HTTP请求句柄,

The following modifiers can be used with WinHttpAddRequestHeaders.

WinHttpAddRequestHeaders可以实现下面改变

Modifier Description
WINHTTP_ADDREQ_FLAG_ADD

Adds the header if it does not exist. Used with WINHTTP_ADDREQ_FLAG_REPLACE.

如果头部不存在,添加它

WINHTTP_ADDREQ_FLAG_ADD_IF_NEW

Adds the header only if it does not already exist; otherwise, an error is returned.

如果头部确实不存在才添加,否则返回错误。

WINHTTP_ADDREQ_FLAG_COALESCE

Merges headers of the same name.

对同名头部信息进行融合

WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA

Merges headers of the same name using a comma. For example, adding “Accept: text/*” followed by “Accept: audio/*” with this flag forms the single header “Accept: text/*, audio/*”, causing the first header found to be merged. It is up to the calling application to ensure a cohesive scheme with respect to merged/separate headers.

WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON Merges headers of the same name using a semicolon.
WINHTTP_ADDREQ_FLAG_REPLACE Replaces or removes a header. If the header value is empty and the header is found, it is removed. If the header value is not empty, the header value is replaced.

 

发送请求

The WinHttpSendRequest function establishes a connection to the server and sends the request to the specified site. This function requires anHINTERNET handle created by WinHttpOpenRequest. WinHttpSendRequest can also send additional headers or optional information. The optional information is generally used for operations that write information to the server, such as PUT and POST.

WinHttpSendRequest函数与服务器建立一个连接,这个函数需要使用WinHttpOpenRequest产生的句柄。WinHttpSendRequest也可以发送附加头部或可选信息,这些附加信息一般是用来向服务器写信息的,例如PUT或者POST。

After the WinHttpSendRequest function sends the request, the application can use theWinHttpReadData and WinHttpQueryDataAvailable functions on the HINTERNET handle to download the server’s resources.

WinHttpSendRequest函数发送数据后,应用程序可以使用WinHttpReadDataWinHttpQueryDataAvailable函数,在HINTERNET句柄上下载服务器资源。

向服务器发送数据

To post data to a server, the HTTP verb in the call to WinHttpOpenRequest must be either POST or PUT. When WinHttpSendRequest is called, the dwTotalLength parameter should be set to the size of the data in bytes. Then useWinHttpWriteData to post the data to the server.

要想服务器发送数据,WinHttpOpenRequest的HTTP verb参数必须是POST或PUT。当调用WinHttpSendRequest时,dwTotalLength参数应该设置为要发送数据的byte大小。然后使用WinHttpWriteData向服务器发送数据。

Alternatively, set the lpOptional parameter of WinHttpSendRequest to the address of a buffer that contains data to post to the server. When using this technique, you must set both thedwOptionalLength anddwTotalLength parameters of WinHttpSendRequest to be the size of the data being posted. CallingWinHttpSendRequest in this manner eliminates the need to callWinHttpWriteData.

另外,设置WinHttpSendRequestlpOptional参数为一个缓冲,这个缓冲中包含要发送的数据。当使用这项技术时,你必须设置WinHttpSendRequest中的dwOptionalLength 和dwTotalLength参数,这些参数由要发送的数据决定。调用WinHttpSendRequest后需要调用WinHttpWriteData

获取请求后的信息

The WinHttpQueryHeaders function allows an application to retrieve information about an HTTP request. The function requires anHINTERNET handle created by WinHttpOpenRequest, an information level value, and a buffer length.WinHttpQueryHeaders also accepts a buffer that stores the information and a zero-based header index that enumerates multiple headers with the same name.

WinHttpQueryHeaders函数允许应用获取HTTP请求中的信息,这个函数需要WinHttpOpenRequest产生的请求句柄,信息级别值和缓冲长度。WinHttpQueryHeaders也接受一个缓冲,这个缓冲中存储着一些信息,和同名的以0序号开始的头部信息。

Use any of the information level values found on the Query Info Flags page with a modifier to control the format in which the information is stored in thelpvBuffer parameter ofWinHttpQueryHeaders.

使用任意可在Query Info Flags页找到的水平值来控制存在WinHttpQueryHeaders函数的lpvBuffer参数里的格式。

从Web上下载资源

After opening a request with the WinHttpOpenRequest function, sending it to the server with WinHttpSendRequest, and preparing the request handle to receive a response withWinHttpReceiveResponse, the application can use the WinHttpReadData and WinHttpQueryDataAvailable functions to download the resource from the HTTP server.

在使用WinHttpOpenRequest打开资源后,使用WinHttpSendRequest向服务器发送请求,准备好WinHttpReceiveResponse的句柄来获取服务器响应。可以使用WinHttpReadData and WinHttpQueryDataAvailable从服务器下载资源。

The following sample code shows how to download a resource with secure transaction semantics. The sample code initializes the WinHTTP application programming interface (API), selects a target HTTPS server, and then opens and sends a request for this secure resource. WinHttpQueryDataAvailable is used with the request handle to determine how much data is available for download, and thenWinHttpReadData is used to read that data. This process is repeated until the entire document has been retrieved and displayed.

下面例程中展示了一个如何使用安全语法下载资源,这个例程初始化WinHTTP程序,选择目标HTTPS服务器,然后打开,发送请求。WinHttpQueryDataAvailable被用来探查有多少数据需要下载,然后使用WinHttpReadData获取这些数据,这个过程一直重复,直到整个文档被下载并且展示。

C++

#include <windows.h>
#include <winhttp.h>
#include <stdio.h>
#pragma comment(lib,"Winhttp.lib")
int main()
{
    
    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_NO_PROXY_NAME, 
                       WINHTTP_NO_PROXY_BYPASS, 0 );
    
    // Specify an HTTP server.
    if( hSession )
        hConnect = WinHttpConnect( hSession, L"192.168.1.101",
                          INTERNET_DEFAULT_HTTPS_PORT, 0 );
    
    // Create an HTTP request handle.
    if( hConnect )
        hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL,
        NULL, WINHTTP_NO_REFERER, 
        WINHTTP_DEFAULT_ACCEPT_TYPES, 
        WINHTTP_FLAG_SECURE );
    
    // Send a request.
    if( hRequest )
        bResults = WinHttpSendRequest( hRequest,
        WINHTTP_NO_ADDITIONAL_HEADERS, 0,
        WINHTTP_NO_REQUEST_DATA, 0, 
        0, 0 );
    
    
    // End the request.
    if( bResults )
        bResults = WinHttpReceiveResponse( hRequest, NULL );
    
    // 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( ) );
            
            // Allocate space for the buffer.
            pszOutBuffer = new char[dwSize+1];
            if( !pszOutBuffer )
            {
                printf( "Out of memory\n" );
                dwSize=0;
            }
            else
            {
                // 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;
            }
        } while( dwSize > 0 );
    }
    
    
    // Report any errors.
    if( !bResults )
        printf( "Error %d has occurred.\n", GetLastError( ) );
    
    // Close any open handles.
    if( hRequest ) WinHttpCloseHandle( hRequest );
    if( hConnect ) WinHttpCloseHandle( hConnect );
    if( hSession ) WinHttpCloseHandle( hSession );
    
    return 0; 
}
PS:自己编译时,发现程序会返回12175错误,下面是12175的错误解决方法,加在    
if( hConnect )
        hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL,
        NULL, WINHTTP_NO_REFERER, 
        WINHTTP_DEFAULT_ACCEPT_TYPES, 
        WINHTTP_FLAG_SECURE );
之后就可以了。
------------------------------------------------------------------
     DWORD  dwFlags;
     DWORD  dwBuffLen =  sizeof (dwFlags);           
     WinHttpQueryOption (hRequest, WINHTTP_OPTION_SECURITY_FLAGS,
         ( LPVOID )&dwFlags, &dwBuffLen);
     dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
     dwFlags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
     dwFlags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
//    dwFlags |= SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
 
     WinHttpSetOption (hRequest, WINHTTP_OPTION_SECURITY_FLAGS,
         &dwFlags,  sizeof  (dwFlags) );
 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/157534.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • IoT — (四) 物联网系统架构介绍[通俗易懂]

    IoT — (四) 物联网系统架构介绍[通俗易懂]  物联网(IoT)是目前最新最热的技术热点之一,也是这个信息化时代的重要发展节点。相对于互联网而言,物联网的本质在于“万物相连”。物联网的核心和基础仍然是互联网,是在互联网基础上延伸和扩展的网络;其用户端延伸和扩展到了任何物品与物品之间,进行信息交换和通信,也就是物物相息。  物联网操作系统概述:尽管物联网的发展形态受到普遍看好和关注,但是“连接、区别、识别、沟通、操作”这五大问题一直如影随形…

  • 手机的分辨率和电脑的分辨率_手机屏幕分辨率大全

    手机的分辨率和电脑的分辨率_手机屏幕分辨率大全电脑分辨率分辨率比例是否淘汰1920*108016:9主流1366*76816:9主流1600*90016:9非主流2560*160016:10非主流1920*120016:10非主流1440*90016:10非主流1680*105016:10非主流1024*7684:3非主流800*6004:3非主流比例=高度/宽度手机分辨率ios型号分辨率像素密度(pp…

  • 数学建模(7)动态规划以及matlab实现

    数学建模(7)动态规划以及matlab实现数学建模(7)动态规划概念运筹学分支,求解多阶段决策过程最优化问题的数学方法思路将复杂的多阶段决策问题分解为一系列的简单,离散的单阶段决策问题,顺序求解法在考虑本阶段最优的情况下兼顾整体最优的解决方法主要处理离散连续型问题特点没有特定的算法,需要具体问题具体分析无后效性马尔科夫性,系统从某个阶段后的发展仅与本阶段所处的状态和以后的决策所做的决策所决定,与之前的状态无关。具体问题企业…

    2022年10月30日
  • hashmap顺序遍历_遍历排序

    hashmap顺序遍历_遍历排序hashmap元素排序想要hashmap中的元素有序可以使用linkedHashMap。HashMap<Integer,User>hashMap=newHashMap<>();hashMap.put(1,newUser(“张三”,32));hashMap.put(2,newUser(“张四”,33));hashMap.put(3,newUser(“王五”,22));//将map转换为一个entry类型的lis

  • 概率论:假设检验-t检验、卡方检验和AD-Fuller test

    概率论:假设检验-t检验、卡方检验和AD-Fuller testhttp://blog.csdn.net/pipisorry/article/details/51184556卡方检验Chi-Squarethechi-squaretestmeasuresdependencebetweenstochasticvariables,sousingthisfunction“weedsout”thefeaturesthatare…

  • 第七章:同步类容器,vector 线程安全与hashmap线程不安全等的举例

    第七章:同步类容器,vector 线程安全与hashmap线程不安全等的举例第七章:同步类容器,vector 线程安全与hashmap线程不安全等的举例

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号