WinHTTP教程

article/2025/10/29 12:32:03

最近有些忙,也没更新BLOG,这几天在捣鼓一个小玩意要用到WinHTTP API,发现资料很少,而且大都是些MFC封装的例子,看得我是一个头几个大。就把自己关于WinHTTP的学习总结了一下,仅供参考,各人理解可能有区别。另外非常感谢前人在网络上提供的相关参考。

BTW:Google Chrome就是基于WinHTTP写的,如果想深入学习,可以阅读分析Chrome Code.
从此处获取Chrome的源代码等相关信息
SVN: http://src.chromium.org/svn/trunk/src/chrome/
VIEW: http://src.chromium.org/viewvc/

WinHTTP APIs是一组用来进行HTTP操作的函数,相比WinINet更加安全和健壮一些。

WinHTTP API List:

WinHttpAddRequestHeaders
WinHttpCheckPlatform
WinHttpCloseHandle
WinHttpConnect
WinHttpCrackUrl
WinHttpCreateUrl
WinHttpDetectAutoProxyConfigUrl
WinHttpGetDefaultProxyConfiguration
WinHttpGetIEProxyConfigForCurrentUser
WinHttpGetProxyForUrl
WinHttpOpen
WinHttpOpenRequest
WinHttpQueryAuthSchemes
WinHttpQueryDataAvailable
WinHttpQueryHeaders
WinHttpQueryOption
WinHttpReadData
WinHttpReceiveResponse
WinHttpSendRequest
WinHttpSetCredentials
WinHttpSetDefaultProxyConfiguration
WinHttpSetOption
WinHttpSetStatusCallback
WinHttpSetTimeouts
WinHttpTimeFromSystemTime
WinHttpTimeToSystemTime
WinHttpWriteData


WinHTTP API逻辑上分成三个独立的对象进行建模:会话对象、连接对象、请求对象。大致为:

初始化WinHTTP(获得会话对象,)-->创建连接(连接1,连接2,...N)-->发送请求(请求1,请求2,....N)

会话对象、连接对象、请求对象都由HINTERNET句柄表示,句柄的使用传递过程大致为:

WinHttpOpen-->return Session handle
                        |
WinHttpConnect-->return Connection handle
                        |
WinHttpOpenRequest-->return Request handle

各对象句柄可以使用WinHttpCloseHandle进行关闭。为了进一步加深了解WinHTTP APIs的调用过程和关系,我们来看下面的图:

                                                           (图来自MSDN)


会话对象
会话对象使用WinHttpOpen函数来进行创建。函数原形如下:

HINTERNET WinHttpOpen(
          __in LPCWSTR   pwszUserAgent,
          __in DWORD   dwAccessType,
          __in LPCWSTR   pwszProxyName,
          __in LPCWSTR   pwszProxyBypass
          __in DWORD   dwFlags
);

第一个参数指向一个应用程序自身名称及版本的字符串,使用在HTTP协议的User Agent中。如:Mozilla/4.0
第二个参数是WinHttp的访问类型要求。可能为下列值
WINHTTP_ACCESS_TYPE_NO_PROXY             //不使用默认代理服务器
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY   //使用默认的代理服务器(储存在注册表中的WINHTTP代理设置,注意:与IE的代理设置不同,为独立的)
WINHTTP_ACCESS_TYPE_NAMED_PROXY //使用指定的代理服务器设置
第三个参数指向一个代理服务器名称的字符串,如果前一个参数dwAccessType未设置为WINHTTP_ACCESS_TYPE_NAMED,这个参数就必须为WINHTTP_NO_PROXY_NMAE。
第四个参数指向一个HTTP服务器列表,其中的服务器不能通过前一个参数指定的代理服务器进行路由(这与IE代理服务器设置中的例外情况设置类似)
第五个参数定义了一个标记,当前只定义了一个标记
WINHTTP_FLAG_ASYNC //指示WinHTTP API将异步执行。

连接对象
连接对象使用WinHttpConnect函数来进行创建(注意前面提到的一个会话对象可以创建多个连接对象)。函数原形如下:

HINTERNET WinHttpConnect(
          __in HINTERNET   hSession,
          __in LPCWSTR   pswzServerName,
          __in INTERNET_PORT   nServerPort
          __in reserved DWORD   dwReserved
);

第一个参数指定连接的所属会话句柄。
第二个参数指定连接的服务器名称或IP地址
第三个参数指定服务器的端口号,这个参数还可以指定为下列值
INTERNET_DEFAULT_HTTP_PORT //使用默认HTTP Service端口号80
INTERNET_DEFAULT_HTTPS_PORT //使用默认HTTPS安全连接端口号443
INTERNET_DEFAULT_PORT //常规HTTP请求使用80,HTTPS请求使用443(这是个便利的参数值)
第四个参数是保留的,必须为0

请求对象
请求对象使用WinHttpOpenRequest函数来进行创建(注意前面提到的一个连接对象可以创建多个请求对象)。从请求对象开始,就进入原本目的HTTP操作了。函数原形如下:

HINTERNET WinHttpOpenRequest(
          __in HINTERNET   hConnect,
          __in LPCWSTR   pwszVerb,
          __in LPCWSTR   pwszObjectName,
          __in LPCWSTR   pwszVersion,
          __in LPCWSTR   pwszReferrer,
          __in LPCWSTR   *ppwszAcceptTypes,
          __in DWORD   dwFlags
)

第一个参数指定请求所属的连接句柄
第二个参数指定HTTP协议动作(如:GET、POST和HEAD),如果此参数为NULL,函数会默认使用GET。
第三个参数指定正在请求的资源名称和相对路径
第四个参数指定使用的HTTP协议版本,如果此参数为NULL,函数会默认使用HTTP/1.1
第五个参数指定引用的URL,如果没有,可以设置为WINHTTP_NO_REFERER
第六个参数指定客户端(本应用程序)将接受的媒体类型(如:image/gif、text/*、*/*),一般可以指定为WIN_HTTP_DEFAULT_ACCEPT_TYPES。
第七个参数指定请求行为标记,如可以指定为WINHTTP_FLAG_SECURE标记发出HTTPS请求,一般可以为0。其他可指定值请参考MSDN,我就不罗列了。


至此介绍了三个WinHTTP API,经过这个过程就基本建立了一个HTTP网络连接。由此我们已经对WInHTTP有了基本概念性的认识。WinHTTP APIs(2)中将再介绍利用WinHTTP API进行更为复杂的操作和实际的应用例子


http://chatgpt.dhexx.cn/article/XhoYlvgN.shtml

相关文章

WinHttp c++ 介绍及应用

一、HTTP协议介绍 http协议的底层协议是TCP协议。TCP协议是基于数据流的传输方式。其又叫做“超文本传输协议”,为什么呢,因为它是将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器,通过因特网传送万维网文档的数据传送协议。 1…

WinHTTP

记录WinHTTP学习过程 一、什么是WinHTTP? WinHTTP的全称是Microsoft Windows HTTP Services, 它提供给开发者一个HTTP客户端应用程序接口(API),通过这种API借助HTTP协议给其他的HTTP服务器发送请求。 二、WinHTTP访问流程 如上图,…

Java递归算法计算5的阶乘

递归 package com.etime.test019; //计算5的阶乘; public class Test15 {public static void main(String[] args) {//调用test1方法,且只调用一次int i test1(5);System.out.println(i);}//定义一个int类型返回值的静态方法public static int test1(i…

Java算法递归与递推

Java算法----递归与递推 递推实现递推思想递归实现递归思想递归实现递推思想递推实现递归思想四种方法的特点思维拓展 问题:给你一个整数n,如果n是奇数,就进行运算nn*31,如果n是偶数,就进行运算nn/2,直到n等…

Java开发 | 数据结构和算法之——递归算法

著名的Pascal之父——Nicklaus Wirth(沃斯)让他获得图灵奖的一句话就是他提出的著名公式:“程序=数据结构+算法”,这个公式对计算机科学的影响类似于爱因斯坦的质能方程在物理界的影响。 因此可以看出来数据结构和算法在我们开发程序中有多么的重要了,下面我们来简单认识…

java中递归算法的理解

Coding多了,递归算法是非常常见的,最近我一直在做树形结构的封装,所以更加的离不开递归算法。所以今天就简单说一下这个递归算法,用java实现一个非常经典的递归实例。 递归算法,其实说白了,就是程序的自身调…

【递归】java递归算法及替代方法

文章目录 菜单树递归(树根往子节点递归)需求: 取所有level小于2的节点 ( 返回结果为普通list格式) 为list格式的数据设置children(非递归)需求: 数据库查出来的原始list 如果有children就设置 使用循环代替…

Java递归

1.递归的概念: 一个方法在执行过程中调用自身, 就称为 "递归". 示例: //递归求n的阶乘 public static void main(String[] args) {int n 5;int ret factor(n);System.out.println("ret " ret); }public static int factor(int…

java递归算法(一)——详解以及几个经典示例

什么是递归 递归就是一个程序或函数在其中定义或说明有之间或者间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个原问题相似的规模较小的问题来求解,递归策略只需要少量的程序就可以描述出解题过程所需要的多次重复计算,大…

Java 递归算法

一、概述: Java递归:简单说就是函数自身直接或间接调用函数的本身。 二、应用场景: 若:一个功能在被重复使用,并每次使用时,参与运算的结果和上一次调用有关,这时就可以使用递归来解决这个问题…

递归与递归算法实例(java实现)

一、递归介绍 递归算法(英语:recursion algorithm)在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。绝大 多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。 定义&#xff1…

Java的递归算法

递归算法设计的基本思想是:对于一个复杂的问题,把原问题分解为若干个相对简单类同的子问题,继续下去直到子问题简单到能够直接求解,也就是说到了递推的出口,这样原问题就有递推得解。 关键要抓住的是: &…

java递归算法实现

Coding多了,递归算法是非常常见的,最近我一直在做树形结构的封装,所以更加的离不开递归算法。所以今天就简单说一下这个递归算法,用java实现一个非常经典的递归实例。 递归算法,其实说白了,就是程序的自身调…

【Java】递归算法

文章目录 什么是递归?递归求阶乘递归求解斐波那契数列猴子吃桃问题 什么是递归? 程序 调用自身 的编程技巧成为 递归(recursion)。 递归算法是一种直接或间接调用、定义自身的函数或方法的算法,也就是调用自身。 递归…

Java递归算法

递归在程序语言中就是方法本身自己调用自己,而递归思想是算法的重要思想之一,就是利用递归来实现解决问题的算法。 递归也分为直接递归和间接递归。 那么什么叫直接递归什么又叫间接递归呢? //直接递归调用 function(){...function();... …

散布矩阵(scatter_matrix)及相关系数(correlation coefficients)实例分析

在进行机器学习建模之前,需要对数据进行分析,判断各特征(属性,维度)的数据分布及其之间的关系成为十分必要的环节,本文利用Pandas和Numpy的散布矩阵函数及相关系数函数对数据集特征及其关系进行实例分析。 散布矩阵(scatter_matri…

Probability And Statistics——CorrelationsCovariance

Skew(偏度) 在概率论和统计学中,偏度衡量实数随机变量概率分布的不对称性。偏度的值可以为正,可以为负或者甚至是无法定义。在数量上,偏度为负(负偏态)就意味着在概率密度函数左侧的尾部比右侧的…

structural covariance network

structural covariance network 结构协方差网络 结构协方差网络是一个较老的概念,只是近年受到了一定的重视。 大佬 Aaron Alexander-Bloch 在2013年通过一篇综述描述了这种结构协方差网络的应用意义及前景。 既往一般是在bold信号和fiber tracking建立连接&#xf…

_variant_t、CComVariant与COleVariant、CDBVariant

目前计算机语言多种多样,如C、Java、Basic、Pascal等,此外还有JavaScript、VBScript、ActionScript等脚本语言,它们各自维护自己的数据类型,当使用C这样强类型的语言来读取数据库或者与其他语言之间来交换数据时,它很有…

Partial correlation coefficient

利用PYTHON计算偏相关系数(Partial correlation coefficient) 在统计学中,我们经常使用皮尔逊相关系数来衡量两个变量之间的线性关系。然而,有时我们感兴趣的是理解两个变量之间的关系,同时控制第三个变量。 例如,假设…