Windows Internet - WinINet 学习笔记(2)

  6.HTTP 会话


使用 WinINet 函数访问WWW资源
(1)初始化 WWW 连接
将服务类型设为 INTERNET_SERVICE_HTTP 调用 InternetConnect 来建立一个 HTTP 会话
HINTERNET InternetConnect(
__in HINTERNET 
hInternet, //InternetOpen 返回的句柄
__in LPCTSTR 
lpszServerName, //可以描述目标服务器的字符串
__in INTERNET_PORT 
nServerPort,//目标服务器的端口
__in LPCTSTR 
lpszUsername,//用户名
__in LPCTSTR 
lpszPassword,//密码
__in DWORD 
dwService,//使用的服务类型
__in DWORD 
dwFlags,
__in DWORD_PTR 
dwContext
);
nServerPort
ValueMeaning

INTERNET_DEFAULT_FTP_PORT

Uses the default port for FTP servers (port 21).

INTERNET_DEFAULT_GOPHER_PORT

Uses the default port for Gopher servers (port 70).

INTERNET_DEFAULT_HTTP_PORT

Uses the default port for HTTP servers (port 80).

INTERNET_DEFAULT_HTTPS_PORT

Uses the default port for Secure Hypertext Transfer Protocol (HTTPS) servers (port 443).

INTERNET_DEFAULT_SOCKS_PORT

Uses the default port for SOCKS firewall servers (port 1080).

INTERNET_INVALID_PORT_NUMBER

Uses the default port for the service specified by dwService.

ldwService
ValueMeaning

INTERNET_SERVICE_FTP

FTP service.

INTERNET_SERVICE_GOPHER

Gopher service.

INTERNET_SERVICE_HTTP

HTTP service.

(2)建立请求

调用 HttpOpenRequest 来建立一个 HTTP 请求,不过这个函数不会自动把请求发送出去,要发送请求需要调用 HttpSendRequest

HttpOpenRequest 原型


HINTERNET HttpOpenRequest(
__in HINTERNET 
hConnect// InternetConnect 函数返回的句柄
__in LPCTSTR lpszVerb// 动作,有GET, PUT, POST。也可以设置为 NULL ,会被当成默认的 GET 来用
__in LPCTSTR lpszObjectName// 一个描述你请求资源的字符串,当请求一个默认页面时令这个参数指向一个空串
__in LPCTSTR lpszVersion// HTTP 版本,这个参数为 NULL 时,默认使用""HTTP/1.1""
__in LPCTSTR lpszReferer// 说明了lpszObjectName是取自哪个文件,可以设为NULL
__in LPCTSTR *lplpszAcceptTypes//
  是一个指向 LPCTSTR数组的指针!数组以一个NULL指针结束。 指定了程序接受的内容的类型,设为空则不接受 任何类型的内容,设为空串则等价于""text/*"",即不接受文本文件以外的图片等文件,只接受某种特定的文件可以用类似"image/gif, image/jpeg"的方式。关于更多内容类型 请看这里
__in DWORD dwFlags// 一般都可以设置为 0
__in DWORD_PTR dwContext // 一般都可以设置为 0
);
(3)添加请求

HttpAddRequestHeaders 原型

BOOL HttpAddRequestHeaders(
   __in HINTERNET hConnect,//HttpOpenRequest 返回的句柄
   __in LPCTSTR lpszHeaders,//包含要添加到请求中的头的字符串的指针,每个头都要以一个 CR/LF (  /r/n/r/n  ) 对结束
   __in DWORD dwHeadersLength,//lpszHeaders指向的字符串的长度(以TCHAR类型记). 如果这个参数被设为-1,则字符串被当作以0结尾的字符串处理,自动计算该字符串的长度
   __in DWORD dwModifiers
);
dwModifiers

可以是下面这些值的组合

ValueMeaning

HTTP_ADDREQ_FLAG_ADD

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

HTTP_ADDREQ_FLAG_ADD_IF_NEW

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

HTTP_ADDREQ_FLAG_COALESCE

Coalesces headers of the same name.

HTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA

Coalesces headers of the same name. For example, adding "Accept: text/*" followed by "Accept: audio/*" with this flag results in the formation of the single header "Accept: text/*, audio/*". This causes the first header found to be coalesced. It is up to the calling application to ensure a cohesive scheme with respect to coalesced/separate headers.

HTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON

Coalesces headers of the same name using a semicolon.

HTTP_ADDREQ_FLAG_REPLACE

Replaces or removes a header. If the header value is empty and the header is found, it is removed. If not empty, the header value is replaced.

(4)发送一个请求

HttpSendRequest

BOOL HttpSendRequest(
__in HINTERNET 
hRequest, //HttpOpenRequst 返回的句柄
__in LPCTSTR 
lpszHeaders, //附加到请求上的头,可以为NULL
__in DWORD 
dwHeadersLength, //lpszHeaders指向的字符串的长度(以TCHAR类型记). 如果这个参数被设为-1,当调用的是HttpSendRequestA时则字符串被当作以0结尾的字符串处理,自动计算该字符串的长度。当调用的是 HttpSendRequestW时就会产生一个错误
__in LPVOID 
lpOptional, //当使用POST或PUT方法时,这个参数指向的数据会紧接着请求被发送出去。没有需要发送的数据则可以设置为NULL
__in DWORD 
dwOptionalLength //lpOptional数据的字节长度,无数据时设置为0
);
(5)向服务器发送数据

方法一:参见上面HttpSentRequest的lpOptional参数的说明

方法二:使用 InternetWriteFile 向一个句柄里发送数据,然后使用 HttpSendRequestEx 发送

(6)查询一个请求的信息

HttpQueryInfo

BOOL HttpQueryInfo(
__in      HINTERNET 
hRequest, /*由 HttpOpenRequest 或 InternetOpenUrl 返回的句柄*/
__in      DWORD 
dwInfoLevel,/*
  Query Info Flags . */
   __inout LPVOID lpvBuffer, /*用于存储查询结果的缓冲区,不可为NULL*/
__inout LPDWORD 
lpdwBufferLength,/*lpvBuffer指向的缓冲区的字节长度
         若函数执行成功,这个变量存储的是写到缓冲区里的数据长度。如果数据是字符串则返回的长度不包括字符串的结束字符
         如果函数发生 ERROR_INSUFFICIENT_BUFFER 错误, 则这个变量里保存的是数据的实际字节长度程序需要根据这个长度重新分配内存,再执行一次这个函数*/
__inout LPDWORD 
lpdwIndex /*没看大明白,不过似乎可以设置为NULL
        Pointer to a zero-based header index used to enumerate multiple headers with the same name.
        When calling the function, this parameter is the index of the specified header to return.
        When the function returns, this parameter is the index of the next header.
        If the next index cannot be found, ERROR_HTTP_HEADER_NOT_FOUND is returned.*/
);
(7) WWW 上下载资源

在调用 HttpOpenRequest 和 HttpSendRequest 之后, 程序可以使用 InternetReadFileInternetQueryDataAvailable,InternetSetFilePointer 来下载HTTP服务器上的资源了。

BOOL InternetQueryDataAvailable(//查询数据的长度
__in HINTERNET
hFile, //由 InternetOpenUrl, FtpOpenFile, GopherOpenFile, 或 HttpOpenRequest
返回的句柄
__out LPDWORD
lpdwNumberOfBytesAvailable, //用于存放数据长度的指针
__in DWORD
dwFlags, //保留参数,置0
__in DWORD_PTR
dwContext //保留参数,置0
);
BOOL InternetReadFile( //读取句柄的数据
__in    HINTERNET hFile, // InternetOpenUrl, FtpOpenFile, GopherOpenFile, HttpOpenRequest 创建的句柄
__out LPVOID lpBuffer, // 存放数据的缓冲区
__in    DWORD dwNumberOfBytesToRead, // 准备读取的字节数
__out LPDWORD lpdwNumberOfBytesRead // 读取了的字节数
);

DWORD InternetSetFilePointer( //设置InternetReadFile的文件位置(莫非多线程下载就是用这个实现的?),服务器不支持随机访问的话函数调用会失败,如果InternetReadFile已经读取到了文件的末尾,这个函数的调用也会失败。
__in HINTERNET hFile, //由 InternetOpenUrl (on an HTTP or HTTPS URL)创建。 或由HttpOpenRequest 创建(使用 GET 或 HEAD方法,而且句柄已经被 HttpSendRequest 访问过了). 
这个句柄也不可以使用 INTERNET_FLAG_DONT_CACHE 或 INTERNET_FLAG_NO_CACHE_WRITE 标志
__in LONG lDistanceToMove, //移动的字节数。正数向后移动,负数向前移动
__in PVOID pReserved, //保留参数,为NULL
__in DWORD dwMoveMethod, //指定了移动指针时的参考点。FILE_BEGIN(使用这个标志时,移动的字节数被当作无符号数处理)、FILE_CURRENT、FILE_END(如果内容的长度无法获得,则使用这个标志时会失败)
__in DWORD_PTR dwContext //保留参数,为NULL
);


PS:Evernote里面编辑好的格式贴这里似乎有问题~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值