Http訪问有两种方式,GET和POST,就编程来说GET方式相对简单点,它不用向server提交数据,在这个例程中我使用POST方式,提交数据value1与value2,并从server得到他们的和(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.
在这个例程中以上各个流程都进行了简单封装,以便对照两套API函数的些许差异。以下让源码说话,原project是一个windows控制台project,你能够非常easy通过拷贝代码重建project。
另:假设你从server得到的返回数据是utf8格式的文本数据,你将须要对返回的数据进行转换才干正确显示中文,日文等。仅供參考,转换为ATL CStringW的函数见下:
1

// HttpPost.cpp written by l_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

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

#ifdef USE_WINHTTP
14

#include <winhttp.h>
15

#pragma comment(lib, "winhttp.lib")
16

#else
17

#include <wininet.h>
18

#pragma comment(lib, "wininet.lib")
19

#endif
20

#define BUF_SIZE (1024)
21

22

// CrackedUrl
23


class CrackedUrl

{
24

int m_scheme;
25

CStringW m_host;
26

int m_port;
27

CStringW m_path;
28

public:
29

CrackedUrl(LPCWSTR url)
30


{
31


URL_COMPONENTS uc =

{ 0};
32

uc.dwStructSize = sizeof(uc);
33

34

const DWORD BUF_LEN = 256;
35

36

WCHAR host[BUF_LEN];
37

uc.lpszHostName = host;
38

uc.dwHostNameLength = BUF_LEN;
39

40

WCHAR path[BUF_LEN];
41

uc.lpszUrlPath = path;
42

uc.dwUrlPathLength = BUF_LEN;
43

44

WCHAR extra[BUF_LEN];
45

uc.lpszExtraInfo = extra;
46

uc.dwExtraInfoLength = BUF_LEN;
47

48

#ifdef USE_WINHTTP
49


if (!WinHttpCrackUrl(url, 0, ICU_ESCAPE, &uc))

{
50

printf("Error:WinHttpCrackUrl failed!/n");
51

}
52

53

#else
54


if (!InternetCrackUrl(url, 0, ICU_ESCAPE, &uc))

{
55

printf("Error:InternetCrackUrl failed!/n");
56

}
57

#endif
58

m_scheme = uc.nScheme;
59

m_host = host;
60

m_port = uc.nPort;
61

m_path = path;
62

}
63

64

int GetScheme() const
65


{
66

return m_scheme;
67

}
68

69

LPCWSTR GetHostName() const
70


{
71

return m_host;
72

}
73

74

int GetPort() const
75


{
76

return m_port;
77

}
78

79

LPCWSTR GetPath() const
80


{
81

return m_path;
82

}
83

84

static CStringA UrlEncode(const char* p)
85


{
86


if (p == 0)

{
87

return CStringA();
88

}
89

90

CStringA buf;
91

92


for (;;)

{
93

int ch = (BYTE) (*(p++));
94


if (ch == '/0')

{
95

break;
96

}
97

98


if (isalnum(ch) || ch == '_' || ch == '-' || ch == '.')

{
99

buf += (char)ch;
100

}
101


else if (ch == ' ')

{
102

buf += '+';
103

}
104


else

{
105

char c[16];
106

wsprintfA(c, "%%%02X", ch);
107

buf += c;
108

}
109

}
110

111

return buf;
112

}
113

};
114

115

// CrackedUrl
116

HINTERNET OpenSession(LPCWSTR userAgent = 0)
117



{
118

#ifdef USE_WINHTTP
119

return WinHttpOpen(userAgent, NULL, NULL, NULL, NULL);;
120

#else
121

return InternetOpen(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
122

#endif
123

}
124

125

HINTERNET Connect(HINTERNET hSession, LPCWSTR serverAddr, int portNo)
126



{
127

#ifdef USE_WINHTTP
128

return WinHttpConnect(hSession, serverAddr, (INTERNET_PORT) portNo, 0);
129

#else
130

return InternetConnect(hSession, serverAddr, portNo, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
131

#endif
132

}
133

134

HINTERNET OpenRequest(HINTERNET hConnect, LPCWSTR verb, LPCWSTR objectName, int scheme)
135



{
136

DWORD flags = 0;
137

#ifdef USE_WINHTTP
138


if (scheme == INTERNET_SCHEME_HTTPS)

{
139

flags |= WINHTTP_FLAG_SECURE;
140

}
141

142

return WinHttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags);
143

144

#else
145


if (scheme == INTERNET_SCHEME_HTTPS)

{
146

flags |= INTERNET_FLAG_SECURE;
147

}
148

149

return HttpOpenRequest(hConnect, verb, objectName, NULL, NULL, NULL, flags, 0);
150

#endif
151

}
152

153

BOOL AddRequestHeaders(HINTERNET hRequest, LPCWSTR header)
154



{
155

SIZE_T len = lstrlenW(header);
156

#ifdef USE_WINHTTP
157

return WinHttpAddRequestHeaders(hRequest, header, DWORD(len), WINHTTP_ADDREQ_FLAG_ADD);
158

#else
159

return HttpAddRequestHeaders(hRequest, header, DWORD(len), HTTP_ADDREQ_FLAG_ADD);
160

#endif
161

}
162

163

BOOL SendRequest(HINTERNET hRequest, const void* body, DWORD size)
164



{
165

#ifdef USE_WINHTTP
166

return WinHttpSendRequest(hRequest, 0, 0, const_cast<void*>(body), size, size, 0);
167

#else
168

return HttpSendRequest(hRequest, 0, 0, const_cast<void*>(body), size);
169

#endif
170

}
171

172

BOOL EndRequest(HINTERNET hRequest)
173



{
174

#ifdef USE_WINHTTP
175

return WinHttpReceiveResponse(hRequest, 0);
176

#else
177

// if you use HttpSendRequestEx to send request then use HttpEndRequest in here!
178

return TRUE;
179

#endif
180

}
181

182

BOOL QueryInfo(HINTERNET hRequest, int queryId, char* szBuf, DWORD* pdwSize)
183



{
184

#ifdef USE_WINHTTP
185

return WinHttpQueryHeaders(hRequest, (DWORD) queryId, 0, szBuf, pdwSize, 0);
186

#else
187

return HttpQueryInfo(hRequest, queryId, szBuf, pdwSize, 0);
188

#endif
189

}
190

191

BOOL ReadData(HINTERNET hRequest, void* buffer, DWORD length, DWORD* cbRead)
192



{
193

#ifdef USE_WINHTTP
194

return WinHttpReadData(hRequest, buffer, length, cbRead);
195

#else
196

return InternetReadFile(hRequest, buffer, length, cbRead);
197

#endif
198

}
199

200

void CloseInternetHandle(HINTERNET hInternet)
201



{
202

if (hInternet)
203


{
204

#ifdef USE_WINHTTP
205

WinHttpCloseHandle(hInternet);
206

#else
207

InternetCloseHandle(hInternet);
208

#endif
209

}
210

}
211

212

int _tmain(int argc, _TCHAR* argv[])
213



{
214

HINTERNET hSession = 0;
215

HINTERNET hConnect = 0;
216

HINTERNET hRequest = 0;
217

CStringW strHeader(L"Content-type: application/x-www-form-urlencoded/r/n");
218

219

// Test data
220

CrackedUrl crackedUrl(L"http://www.easy-creator.net/test2/add.asp");
221

CStringA strPostData("value1=10&value2=14");
222

223

// Open session.
224

hSession = OpenSession(L"HttpPost by l_zhaohui@163.com");
225


if (hSession == NULL)

{
226

printf("Error:Open session!/n");
227

return -1;
228

}
229

230

// Connect.
231

hConnect = Connect(hSession, crackedUrl.GetHostName(), crackedUrl.GetPort());
232


if (hConnect == NULL)

{
233

printf("Error:Connect failed!/n");
234

return -1;
235

}
236

237

// Open request.
238

hRequest = OpenRequest(hConnect, L"POST", crackedUrl.GetPath(), crackedUrl.GetScheme());
239


if (hRequest == NULL)

{
240

printf("Error:OpenRequest failed!/n");
241

return -1;
242

}
243

244

// Add request header.
245


if (!AddRequestHeaders(hRequest, strHeader))

{
246

printf("Error:AddRequestHeaders failed!/n");
247

return -1;
248

}
249

250

// Send post data.
251


if (!SendRequest(hRequest, (const char*)strPostData, strPostData.GetLength()))

{
252

printf("Error:SendRequest failed!/n");
253

return -1;
254

}
255

256

// End request
257


if (!EndRequest(hRequest))

{
258

printf("Error:EndRequest failed!/n");
259

return -1;
260

}
261

262

char szBuf[BUF_SIZE];
263

DWORD dwSize = 0;
264

szBuf[0] = 0;
265

266

// Query header info.
267

#ifdef USE_WINHTTP
268

int contextLengthId = WINHTTP_QUERY_CONTENT_LENGTH;
269

int statusCodeId = WINHTTP_QUERY_STATUS_CODE;
270

int statusTextId = WINHTTP_QUERY_STATUS_TEXT;
271

#else
272

int contextLengthId = HTTP_QUERY_CONTENT_LENGTH;
273

int statusCodeId = HTTP_QUERY_STATUS_CODE;
274

int statusTextId = HTTP_QUERY_STATUS_TEXT;
275

#endif
276

dwSize = BUF_SIZE;
277


if (QueryInfo(hRequest, contextLengthId, szBuf, &dwSize))

{
278

szBuf[dwSize] = 0;
279

printf("Content length:[%s]/n", szBuf);
280

}
281

282

dwSize = BUF_SIZE;
283


if (QueryInfo(hRequest, statusCodeId, szBuf, &dwSize))

{
284

szBuf[dwSize] = 0;
285

printf("Status code:[%s]/n", szBuf);
286

}
287

288

dwSize = BUF_SIZE;
289


if (QueryInfo(hRequest, statusTextId, szBuf, &dwSize))

{
290

szBuf[dwSize] = 0;
291

printf("Status text:[%s]/n", szBuf);
292

}
293

294

// read data.
295


for (;;)

{
296

dwSize = BUF_SIZE;
297


if (ReadData(hRequest, szBuf, dwSize, &dwSize) == FALSE)

{
298

break;
299

}
300

301


if (dwSize <= 0)

{
302

break;
303

}
304

305

szBuf[dwSize] = 0;
306

printf("%s/n", szBuf); //Output value = value1 + value2
307

}
308

309

CloseInternetHandle(hRequest);
310

CloseInternetHandle(hConnect);
311

CloseInternetHandle(hSession);
312

313

return 0;
314

}
315