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) );
 

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 比太钱包使用方法及冷钱包存储方案-2

    拖更一个月的我又开始更新了。过完年,恰逢数字货币开始上涨,正好是聊聊钱包的好时候。上文说到比太钱包的冷热模式,这次接上文写冷钱包模式下的发币及公钥监控操作。先从冷钱包模式下发币说起吧:1,打开钱包,点击发送按钮。2,输入收款地址和金额,并点击发送。这里无论是输入比特币金额还是法币金额,钱包会自动换算出另一种货币金额。3,输入钱包密码,准备冷钱包签名。4,生成未签名的交易信息二维码,需使用装有对应…

    2022年4月5日
    156
  • Java中CAS 基本实现原理「建议收藏」

    Java中CAS 基本实现原理「建议收藏」一、前言了解CAS,首先要清楚JUC,那么什么是JUC呢?JUC就是java.util.concurrent包的简称。它有核心就是CAS与AQS。CAS是java.util.concurrent.atomic包的基础,如AtomicInteger、AtomicBoolean、AtomicLong等等类都是基于CAS。什么是CAS呢?全称CompareAndSwap,比较并交换。CAS有三个操作数,内存值V,旧的预期值E,要修改的新值N。当且仅当预期值E和内存值V相同时,将内存值V修改为N,否则什

    2022年7月8日
    37
  • 新后缀supporthelpgood勒索病毒出现 解密sql文件 恢复成功mdf

    新后缀supporthelpgood勒索病毒出现 解密sql文件 恢复成功mdf

    2021年7月7日
    97
  • 机器学习中的目标函数、损失函数、代价函数有什么区别?

    机器学习中的目标函数、损失函数、代价函数有什么区别?

    2021年11月21日
    45
  • 带你了解软件系统架构的演变

    带你了解软件系统架构的演变一个成熟的系统,并不是一开始就做到方方面面都完美,也不会去考虑什么高并发,高可用问题,但随着时间的推移,现有架构的问题就会慢慢的显现。比如用户激增,访问量不断增大,在这过程中,会不断的出现新的问题,而为了解决这些问题,软件技术架构都会发生重大变化,而针对不同业务特征的系统会有各自的侧重点,像淘宝这类网站要解决的事海量商品搜索下单支付等问题。像腾讯要解决数亿级别用户的实施消息传输等。每种业务都有自己不同的系统架构。以JavaWeb为例搭建简单的电商系统这个电商系统有多个业务模块,假设现在有:.

    2022年6月17日
    25
  • 惠普电脑蓝屏开不了机怎么解决_hp服务器售后电话800

    惠普电脑蓝屏开不了机怎么解决_hp服务器售后电话800在日常生活中,电脑出现蓝屏的无法启动的问题很常见,怎么处理电脑蓝屏问题呢?下面是小编为大家整理的关于hp电脑蓝屏后无法启动的相关资料,希望对您有所帮助!hp电脑蓝屏后无法启动的解决方法很多时候电脑蓝屏是因为电脑的硬件,电脑关机完成后,我们可以断开电脑的电源,然后对我们的内存条擦拭后,从新装机到我们的电脑主板上。清理电脑的各项主板接口也是必须的,我们可以根据顺序,依次清理电脑的各个接口,完成后即可。…

    2022年8月13日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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