使用WinINet和WinHTTP实现Http访问

使用WinINetWinHTTP实现Http访问

飘飘白云 l_zhaohui@163.com <chsdate year="2007" month="11" day="30" islunardate="False" isrocdate="False" w:st="on">2007-11-30</chsdate>

Http访问有两种方式,GET和POST,就编程来说GET方式相对简单点,它不用向服务器提交数据,在这个例程中我使用POST方式,提交数据value1与value2,并从服务器得到他们的和(value1 + value2)。

为实现Http访问,微软提供了二套API:WinINet, WinHTTP。WinHTTP比WinINet更加安全和健壮,可以这么认为WinHTTP是WinINet的升级版本。这两套API包含了很多相似的函数与宏定义,呵呵,详细对比请查阅msdn中的文章“Porting WinINet Applications to WinHTTP”,在线MSDN连接:http://msdn2.microsoft.com/en-us/library/aa384068.aspx。在这个例程中,通过一个宏的设置来决定是使用WinHttp还是WinINet。代码如下:

#define USE_WINHTTP //Comment this line to user wininet.

下面来说说实现Http访问的流程(两套API都一样的流程):

1, 首先我们打开一个Session获得一个HINTERNET session句柄;

2, 然后我们使用这个session句柄与服务器连接得到一个HINTERNET connect句柄;

3, 这样我们使用这个connect句柄来打开Http 请求得到一个HINTERNET request句柄;

4, 这样我们就可以使用这个request句柄来发送数据与读取从服务器返回的数据;

5, 最后依次关闭request,connect,session句柄。

在这个例程中以上各个流程都进行了简单封装,以便对比两套API函数的些许差异。下面让源代码说话,原工程是一个windows控制台工程,你可以很容易通过拷贝代码重建工程。

另:如果你从服务器得到的返回数据是utf8格式的文本数据,你将需要对返回的数据进行转换才能争取显示(中文,日文等)。仅供参考,转换为ATL CStringW的函数见下:

CStringWGetStringWFromUtf8( const std::string & str)
{
intlen=MultiByteToWideChar(CP_UTF8,0,str.c_str(),int(str.length()),0,0);

CStringWbuf;
WCHAR
*dd=buf.GetBuffer(len);

len
=MultiByteToWideChar(CP_UTF8,0,str.c_str(),int(str.length()),dd,len);

buf.ReleaseBuffer(len);

returnbuf;
}

完整代码如下:
1 // HttpPost.cppwrittenbyl_zhaohui@163.com
2 // 2007/11/30
3 #include " stdafx.h "
4 #include < windows.h >
5 #include < stdio.h >
6 #include < stdlib.h >
7
8 #define_ATL_CSTRING_EXPLICIT_CONSTRUCTORS
9 #include < atlbase.h >
10 #include < atlstr.h >
11
12 #defineUSE_WINHTTP // Commentthislinetouserwininet.
13 #ifdefUSE_WINHTTP
14 #include < winhttp.h >
15 #pragmacomment(lib, " winhttp.lib " )
16 # else
17 #include < wininet.h >
18 #pragmacomment(lib, " wininet.lib " )
19 #endif
20 #defineBUF_SIZE( 1024 )
21
22 // CrackedUrl
23 class CrackedUrl {
24intm_scheme;
25CStringWm_host;
26intm_port;
27CStringWm_path;
28public:
29CrackedUrl(LPCWSTRurl)
30{
31URL_COMPONENTSuc={0};
32uc.dwStructSize=sizeof(uc);
33
34constDWORDBUF_LEN=256;
35
36WCHARhost[BUF_LEN];
37uc.lpszHostName=host;
38uc.dwHostNameLength=BUF_LEN;
39
40WCHARpath[BUF_LEN];
41uc.lpszUrlPath=path;
42uc.dwUrlPathLength=BUF_LEN;
43
44WCHARextra[BUF_LEN];
45uc.lpszExtraInfo=extra;
46uc.dwExtraInfoLength=BUF_LEN;
47
48#ifdefUSE_WINHTTP
49if(!WinHttpCrackUrl(url,0,ICU_ESCAPE,&uc)){
50printf("Error:WinHttpCrackUrlfailed!/n");
51}

52
53#else
54if(!InternetCrackUrl(url,0,ICU_ESCAPE,&uc)){
55printf("Error:InternetCrackUrlfailed!/n");
56}

57#endif
58m_scheme=uc.nScheme;
59m_host=host;
60m_port=uc.nPort;
61m_path=path;
62}

63
64intGetScheme()const
65{
66returnm_scheme;
67}

68
69LPCWSTRGetHostName()const
70{
71returnm_host;
72}

73
74intGetPort()const
75{
76returnm_port;
77}

78
79LPCWSTRGetPath()const
80{
81returnm_path;
82}

83
84staticCStringAUrlEncode(constchar*p)
85{
86if(p==0){
87returnCStringA();
88}

89
90CStringAbuf;
91
92for(;;){
93intch=(BYTE)(*(p++));
94if(ch=='/0'){
95break;
96}

97
98if(isalnum(ch)||ch=='_'||ch=='-'||ch=='.'){
99buf+=(char)ch;
100}

101elseif(ch==''){
102buf+='+';
103}

104else{
105charc[16];
106wsprintfA(c,"%%%02X",ch);
107buf+=c;
108}

109}

110
111returnbuf;
112}

113}
;
114
115 // CrackedUrl
116 HINTERNETOpenSession(LPCWSTRuserAgent = 0 )
117 {
118#ifdefUSE_WINHTTP
119returnWinHttpOpen(userAgent,NULL,NULL,NULL,NULL);;
120#else
121returnInternetOpen(userAgent,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0);
122#endif
123}

124
125 HINTERNETConnect(HINTERNEThSession,LPCWSTRserverAddr, int portNo)
126 {
127#ifdefUSE_WINHTTP
128returnWinHttpConnect(hSession,serverAddr,(INTERNET_PORT)portNo,0);
129#else
130returnInternetConnect(hSession,serverAddr,portNo,NULL,NULL,INTERNET_SERVICE_HTTP,0,0);
131#endif
132}

133
134 HINTERNETOpenRequest(HINTERNEThConnect,LPCWSTRverb,LPCWSTRobjectName, int scheme)
135 {
136DWORDflags=0;
137#ifdefUSE_WINHTTP
138if(scheme==INTERNET_SCHEME_HTTPS){
139flags|=WINHTTP_FLAG_SECURE;
140}

141
142returnWinHttpOpenRequest(hConnect,verb,objectName,NULL,NULL,NULL,flags);
143
144#else
145if(scheme==INTERNET_SCHEME_HTTPS){
146flags|=INTERNET_FLAG_SECURE;
147}

148
149returnHttpOpenRequest(hConnect,verb,objectName,NULL,NULL,NULL,flags,0);
150#endif
151}

152
153 BOOLAddRequestHeaders(HINTERNEThRequest,LPCWSTRheader)
154 {
155SIZE_Tlen=lstrlenW(header);
156#ifdefUSE_WINHTTP
157returnWinHttpAddRequestHeaders(hRequest,header,DWORD(len),WINHTTP_ADDREQ_FLAG_ADD);
158#else
159returnHttpAddRequestHeaders(hRequest,header,DWORD(len),HTTP_ADDREQ_FLAG_ADD);
160#endif
161}

162
163 BOOLSendRequest(HINTERNEThRequest, const void * body,DWORDsize)
164 {
165#ifdefUSE_WINHTTP
166returnWinHttpSendRequest(hRequest,0,0,const_cast<void*>(body),size,size,0);
167#else
168returnHttpSendRequest(hRequest,0,0,const_cast<void*>(body),size);
169#endif
170}

171
172 BOOLEndRequest(HINTERNEThRequest)
173 {
174#ifdefUSE_WINHTTP
175returnWinHttpReceiveResponse(hRequest,0);
176#else
177//ifyouuseHttpSendRequestExtosendrequestthenuseHttpEndRequestinhere!
178returnTRUE;
179#endif
180}

181
182 BOOLQueryInfo(HINTERNEThRequest, int queryId, char * szBuf,DWORD * pdwSize)
183 {
184#ifdefUSE_WINHTTP
185returnWinHttpQueryHeaders(hRequest,(DWORD)queryId,0,szBuf,pdwSize,0);
186#else
187returnHttpQueryInfo(hRequest,queryId,szBuf,pdwSize,0);
188#endif
189}

190
191 BOOLReadData(HINTERNEThRequest, void * buffer,DWORDlength,DWORD * cbRead)
192 {
193#ifdefUSE_WINHTTP
194returnWinHttpReadData(hRequest,buffer,length,cbRead);
195#else
196returnInternetReadFile(hRequest,buffer,length,cbRead);
197#endif
198}

199
200 void CloseInternetHandle(HINTERNEThInternet)
201 {
202if(hInternet)
203{
204#ifdefUSE_WINHTTP
205WinHttpCloseHandle(hInternet);
206#else
207InternetCloseHandle(hInternet);
208#endif
209}

210}

211
212 int _tmain( int argc,_TCHAR * argv[])
213 {
214HINTERNEThSession=0;
215HINTERNEThConnect=0;
216HINTERNEThRequest=0;
217CStringWstrHeader(L"Content-type:application/x-www-form-urlencoded/r/n");
218
219//Testdata
220CrackedUrlcrackedUrl(L"http://www.easy-creator.net/test2/add.asp");
221CStringAstrPostData("value1=10&value2=14");
222
223//Opensession.
224hSession=OpenSession(L"HttpPostbyl_zhaohui@163.com");
225if(hSession==NULL){
226printf("Error:Opensession!/n");
227return-1;
228}

229
230//Connect.
231hConnect=Connect(hSession,crackedUrl.GetHostName(),crackedUrl.GetPort());
232if(hConnect==NULL){
233printf("Error:Connectfailed!/n");
234return-1;
235}

236
237//Openrequest.
238hRequest=OpenRequest(hConnect,L"POST",crackedUrl.GetPath(),crackedUrl.GetScheme());
239if(hRequest==NULL){
240printf("Error:OpenRequestfailed!/n");
241return-1;
242}

243
244//Addrequestheader.
245if(!AddRequestHeaders(hRequest,strHeader)){
246printf("Error:AddRequestHeadersfailed!/n");
247return-1;
248}

249
250//Sendpostdata.
251if(!SendRequest(hRequest,(constchar*)strPostData,strPostData.GetLength())){
252printf("Error:SendRequestfailed!/n");
253return-1;
254}

255
256//Endrequest
257if(!EndRequest(hRequest)){
258printf("Error:EndRequestfailed!/n");
259return-1;
260}

261
262charszBuf[BUF_SIZE];
263DWORDdwSize=0;
264szBuf[0]=0;
265
266//Queryheaderinfo.
267#ifdefUSE_WINHTTP
268intcontextLengthId=WINHTTP_QUERY_CONTENT_LENGTH;
269intstatusCodeId=WINHTTP_QUERY_STATUS_CODE;
270intstatusTextId=WINHTTP_QUERY_STATUS_TEXT;
271#else
272intcontextLengthId=HTTP_QUERY_CONTENT_LENGTH;
273intstatusCodeId=HTTP_QUERY_STATUS_CODE;
274intstatusTextId=HTTP_QUERY_STATUS_TEXT;
275#endif
276dwSize=BUF_SIZE;
277if(QueryInfo(hRequest,contextLengthId,szBuf,&dwSize)){
278szBuf[dwSize]=0;
279printf("Contentlength:[%s]/n",szBuf);
280}

281
282dwSize=BUF_SIZE;
283if(QueryInfo(hRequest,statusCodeId,szBuf,&dwSize)){
284szBuf[dwSize]=0;
285printf("Statuscode:[%s]/n",szBuf);
286}

287
288dwSize=BUF_SIZE;
289if(QueryInfo(hRequest,statusTextId,szBuf,&dwSize)){
290szBuf[dwSize]=0;
291printf("Statustext:[%s]/n",szBuf);
292}

293
294//readdata.
295for(;;){
296dwSize=BUF_SIZE;
297if(ReadData(hRequest,szBuf,dwSize,&dwSize)==FALSE){
298break;
299}

300
301if(dwSize<=0){
302break;
303}

304
305szBuf[dwSize]=0;
306printf("%s/n",szBuf);//Outputvalue=value1+value2
307}

308
309CloseInternetHandle(hRequest);
310CloseInternetHandle(hConnect);
311CloseInternetHandle(hSession);
312
313return0;
314}

315
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WinHTTP提供以下功能: WinHttpAddRequestHeaders 向HTTP请求句柄添加一个或多个HTTP请求标头。 WinHttpCheckPlatform 确定WinHTTP是否支持当前平台。 WinHttpCloseHandle 关闭单个 HINTERNET句柄。 WinHttpConnect 指定HTTP请求的初始目标服务器。 WinHttpCrackUrl 将URL分为其组成部分,例如主机名和路径。 WinHttpCreateProxyResolver 创建WinHttpGetProxyForUrlEx使用的句柄。 WinHttpCreateUrl 从组件部分创建URL,例如主机名和路径。 WinHttpDetectAutoProxyConfigUrl 查找代理自动配置(PAC)文件的URL。此功能报告PAC文件的URL,但不下载该文件。 WinHttpFreeProxyResult 释放从以前的调用WinHttpGetProxyResult检索的数据。 WinHttpGetDefaultProxyConfiguration 从注册表中检索默认的WinHTTP代理配置。 WinHTTPGetIEProxyConfigForCurrentUser 获取当前用户的Internet Explorer(IE)代理配置。 WinHttpGetProxyForUrl 检索指定URL的代理信息。 WinHttpGetProxyForUrlEx 检索指定URL的代理信息。 WinHttpGetProxyResult 检索到调用的结果WinHttpGetProxyForUrlEx。 WinHttpOpen 初始化应用程序对WinHTTP功能的使用WinHttpOpenRequest 创建HTTP请求句柄。 WinHttpQueryAuthSchemes 返回服务器支持的授权方案。 WinHttpQueryDataAvailable 返回可立即与读取数据的字节数 WinHttpReadData。 WinHttpQueryHeaders 检索与HTTP请求相关联的头信息。 WinHttpQueryOption 在指定的句柄上查询Internet选项。 WinHttpReadData 从WinHttpOpenRequest函数打开的句柄中读取数据 。 WinHttpReceiveResponse 结束由WinHttpSendRequest启动的HTTP请求 。 WinHttpResetAutoProxy 重置自动代理。 WinHttpSendRequest 将指定的请求发送到HTTP服务器。 WinHttpSetCredentials 将所需的授权凭证传递给服务器。 WinHttpSetDefaultProxyConfiguration 在注册表中设置默认的WinHTTP代理配置。 WinHttpSetOption 设置Internet选项。 WinHttpSetStatusCallback 设置WinHTTP可以在操作过程中进行调用的回调函数。 WinHttpSetTimeouts 设置涉及HTTP事务的各种超时。 WinHttpTimeFromSystemTime 根据HTTP版本1.0规范格式化日期和时间。 WinHttpTimeToSystemTime 获取HTTP时间/日期字符串并将其转换为 SYSTEMTIME结构。 WinHttpWriteData 将请求数据写入HTTP服务器。 WinHttpWebSocketClose 关闭WebSocket连接。 WinHttpWebSocketCompleteUpgrade 完成由WinHttpSendRequest启动的WebSocket握手。 WinHttpWebSocketQueryCloseStatus 获取服务器发送的关闭状态。 WinHttpWebSocketReceive 从WebSocket连接接收数据。 WinHttpWebSocketSend 通过WebSocket连接发送数据。 WinHttpWebSocketShutdown 向WebSocket连接发送关闭框架
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值