.NET实现HTTP协议中的GET、POST请求
这个代码网上找,觉得不错,放到这里和大家分享,非常有用。
1
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Net;5
using System.Net.Sockets;6
using System.Collections;7
using System.IO;8
using System.Text.RegularExpressions;9
using RE = System.Text.RegularExpressions.Regex;10
using System.Security.Cryptography.X509Certificates;11

12

/**//***************************************************************************************************************************************************13
* *文件名:HttpProc.cs14
* *创建人:HeDaode15
* *日 期:2007.09.0116
* *描 述:实现HTTP协议中的GET、POST请求17
* *使 用:HttpProc.WebClient client = new HttpProc.WebClient();18
client.Encoding = System.Text.Encoding.Default;//默认编码方式,根据需要设置其他类型19
client.OpenRead("http://www.baidu.com");//普通get请求20
MessageBox.Show(client.RespHtml);//获取返回的网页源代码21
client.DownloadFile("http://www.loopc.com/upload/163album.rar",@"C:\163album.rar");//下载文件22
client.OpenRead("http://passport.baidu.com/?login","username=zhangsan&password=123456");//提交表单,此处是登录百度的示例23
client.UploadFile("http://hiup.baidu.com/zhangsan/upload", @"file1=D:\1.mp3");//上传文件24
client.UploadFile("http://hiup.baidu.com/zhangsan/upload", "folder=myfolder&size=4003550",@"file1=D:\1.mp3");//提交含文本域和文件域的表单25
*****************************************************************************************************************************************************/26

27
namespace HttpProc28


{29

/**////<summary>30
///上传事件委托31
///</summary>32
///<param name="sender"></param>33
///<param name="e"></param>34
public delegate void WebClientUploadEvent(object sender, HttpProc.UploadEventArgs e);35

36

/**////<summary>37
///下载事件委托38
///</summary>39
///<param name="sender"></param>40
///<param name="e"></param>41
public delegate void WebClientDownloadEvent(object sender, HttpProc.DownloadEventArgs e);42

43

44

/**////<summary>45
///上传事件参数46
///</summary>47
public struct UploadEventArgs48

{49

/**////<summary>50
///上传数据总大小51
///</summary>52
public long totalBytes;53

/**////<summary>54
///已发数据大小55
///</summary>56
public long bytesSent;57

/**////<summary>58
///发送进度(0-1)59
///</summary>60
public double sendProgress;61

/**////<summary>62
///发送速度Bytes/s63
///</summary>64
public double sendSpeed;65
}66

67

/**////<summary>68
///下载事件参数69
///</summary>70
public struct DownloadEventArgs71

{72

/**////<summary>73
///下载数据总大小74
///</summary>75
public long totalBytes;76

/**////<summary>77
///已接收数据大小78
///</summary>79
public long bytesReceived;80

/**////<summary>81
///接收数据进度(0-1)82
///</summary>83
public double ReceiveProgress;84

/**////<summary>85
///当前缓冲区数据86
///</summary>87
public byte[] receivedBuffer;88

/**////<summary>89
///接收速度Bytes/s90
///</summary>91
public double receiveSpeed;92
}93

94

/**////<summary>95
///实现向WEB服务器发送和接收数据96
///</summary>97
public class WebClient98

{99
private WebHeaderCollection requestHeaders, responseHeaders;100
private TcpClient clientSocket;101
private MemoryStream postStream;102
private Encoding encoding = Encoding.Default;103
private const string BOUNDARY = "--HEDAODE--";104
private const int SEND_BUFFER_SIZE = 10245;105
private const int RECEIVE_BUFFER_SIZE = 10245;106
private string cookie = "";107
private string respHtml = "";108
private string strRequestHeaders = "";109
private string strResponseHeaders = "";110
private int statusCode = 0;111
private bool isCanceled = false;112
public event WebClientUploadEvent UploadProgressChanged;113
public event WebClientDownloadEvent DownloadProgressChanged;114

115

/**////<summary>116
///初始化WebClient类117
///</summary>118
public WebClient()119

{120
responseHeaders = new WebHeaderCollection();121
requestHeaders = new WebHeaderCollection();122
}123

124

125

/**////<summary>126
///读取指定URL的文本127
///</summary>128
///<param name="URL">请求的地址</param>129
///<returns>服务器响应文本</returns>130
public string OpenRead(string URL)131

{132
requestHeaders.Add("Connection", "close");133
SendRequestData(URL, "GET");134
return GetHtml();135
}136

137

138
//解决证书过期无法访问的问题139
class CertPolicy : ICertificatePolicy140

{141
public bool CheckValidationResult(ServicePoint srvpt, X509Certificate cert, WebRequest req, int certprb)142

{ return true; }143
}144

145

/**////<summary>146
///采用https协议访问网络147
///</summary>148
///<param name="URL">url地址</param>149
///<param name="strPostdata">发送的数据</param>150
///<returns></returns>151
public string OpenReadWithHttps(string URL, string strPostdata)152

{153
ServicePointManager.CertificatePolicy = new CertPolicy();154
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);155
request.CookieContainer = new CookieContainer();156
request.Method = "POST";157
request.Accept = "*/*";158
request.ContentType = "application/x-www-form-urlencoded";159
byte[] buffer = this.encoding.GetBytes(strPostdata);160
request.ContentLength = buffer.Length;161
request.GetRequestStream().Write(buffer, 0, buffer.Length);162
HttpWebResponse response = (HttpWebResponse)request.GetResponse();163
StreamReader reader = new StreamReader(response.GetResponseStream(), encoding);164
this.respHtml = reader.ReadToEnd();165
foreach (System.Net.Cookie ck in response.Cookies)166

{167
this.cookie += ck.Name + "=" + ck.Value + ";";168
}169
reader.Close();170
return respHtml;171
}172

173

/**////<summary>174
///读取指定URL的文本175
///</summary>176
///<param name="URL">请求的地址</param>177
///<param name="postData">向服务器发送的文本数据</param>178
///<returns>服务器响应文本</returns>179
public string OpenRead(string URL, string postData)180

{181
byte[] sendBytes = encoding.GetBytes(postData);182
postStream = new MemoryStream();183
postStream.Write(sendBytes, 0, sendBytes.Length);184

185
requestHeaders.Add("Content-Length", postStream.Length.ToString());186
requestHeaders.Add("Content-Type", "application/x-www-form-urlencoded");187
requestHeaders.Add("Connection", "close");188

189
SendRequestData(URL, "POST");190
return GetHtml();191
}192

193

194

/**////<summary>195
///读取指定URL的流196
///</summary>197
///<param name="URL">请求的地址</param>198
///<param name="postData">向服务器发送的数据</param>199
///<returns>服务器响应流</returns>200
public Stream GetStream(string URL, string postData)201

{202
byte[] sendBytes = encoding.GetBytes(postData);203
postStream = new MemoryStream();204
postStream.Write(sendBytes, 0, sendBytes.Length);205

206
requestHeaders.Add("Content-Length", postStream.Length.ToString());207
requestHeaders.Add("Content-Type", "application/x-www-form-urlencoded");208
requestHeaders.Add("Connection", "close");209

210
SendRequestData(URL, "POST");211

212
MemoryStream ms = new MemoryStream();213
SaveNetworkStream(ms);214
return ms;215
}216

217

218

/**////<summary>219
///上传文件到服务器220
///</summary>221
///<param name="URL">请求的地址</param>222
///<param name="fileField">文件域(格式如:file1=C:\test.mp3&file2=C:\test.jpg)</param>223
///<returns>服务器响应文本</returns>224
public string UploadFile(string URL, string fileField)225

{226
return UploadFile(URL, "", fileField);227
}228

229

/**////<summary>230
///上传文件和数据到服务器231
///</summary>232
///<param name="URL">请求地址</param>233
///<param name="textField">文本域(格式为:name1=value1&name2=value2)</param>234
///<param name="fileField">文件域(格式如:file1=C:\test.mp3&file2=C:\test.jpg)</param>235
///<returns>服务器响应文本</returns>236
public string UploadFile(string URL, string textField, string fileField)237

{238
postStream = new MemoryStream();239

240
if (textField != "" && fileField != "")241

{242
WriteTextField(textField);243
WriteFileField(fileField);244
}245
else if (fileField != "")246

{247
WriteFileField(fileField);248
}249
else if (textField != "")250

{251
WriteTextField(textField);252
}253
else254
throw new Exception("文本域和文件域不能同时为空。");255

256
//写入结束标记257
byte[] buffer = encoding.GetBytes("--" + BOUNDARY + "--\r\n");258
postStream.Write(buffer, 0, buffer.Length);259

260
//添加请求标头261
requestHeaders.Add("Content-Length", postStream.Length.ToString());262
requestHeaders.Add("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);263
requestHeaders.Add("Connection", "Keep-Alive");264

265
//发送请求数据266
SendRequestData(URL, "POST", true);267

268
//返回响应文本269
return GetHtml();270
}271

272

273

/**////<summary>274
///分析文本域,添加到请求流275
///</summary>276
///<param name="textField">文本域</param>277
private void WriteTextField(string textField)278

{279
string[] strArr = RE.Split(textField, "&");280
textField = "";281
foreach (string var in strArr)282

{283
Match M = RE.Match(var, "([^=]+)=(.+)");284
textField += "--" + BOUNDARY + "\r\n";285
textField += "Content-Disposition: form-data; name=\"" + M.Groups[1].Value + "\"\r\n\r\n" + M.Groups[2].Value + "\r\n";286
}287
byte[] buffer = encoding.GetBytes(textField);288
postStream.Write(buffer, 0, buffer.Length);289
}290

291

/**////<summary>292
///分析文件域,添加到请求流293
///</summary>294
///<param name="fileField">文件域</param>295
private void WriteFileField(string fileField)296

{297
string filePath = "";298
int count = 0;299
string[] strArr = RE.Split(fileField, "&");300
foreach (string var in strArr)301

{302
Match M = RE.Match(var, "([^=]+)=(.+)");303
filePath = M.Groups[2].Value;304
fileField = "--" + BOUNDARY + "\r\n";305
fileField += "Content-Disposition: form-data; name=\"" + M.Groups[1].Value + "\"; filename=\"" + Path.GetFileName(filePath) + "\"\r\n";306
fileField += "Content-Type: image/jpeg\r\n\r\n";307
308
byte[] buffer = encoding.GetBytes(fileField);309
postStream.Write(buffer, 0, buffer.Length);310
311
//添加文件数据312
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);313
buffer = new byte[50000];314
315
do316

{317
count = fs.Read(buffer, 0, buffer.Length);318
postStream.Write(buffer, 0, count);319
320
} while (count > 0);321
322
fs.Close();323
fs.Dispose();324
fs = null;325
326
buffer = encoding.GetBytes("\r\n");327
postStream.Write(buffer, 0, buffer.Length);328
}329
}330

331

/**////<summary>332
///从指定URL下载数据流333
///</summary>334
///<param name="URL">请求地址</param>335
///<returns>数据流</returns>336
public Stream DownloadData(string URL)337

{338
requestHeaders.Add("Connection", "close");339
SendRequestData(URL, "GET");340
MemoryStream ms = new MemoryStream();341
SaveNetworkStream(ms, true);342
return ms;343
}344

345

346

/**////<summary>347
///从指定URL下载文件348
///</summary>349
///<param name="URL">文件URL地址</param>350
///<param name="fileName">文件保存路径,含文件名(如:C:\test.jpg)</param>351
public void DownloadFile(string URL, string fileName)352

{353
requestHeaders.Add("Connection", "close");354
SendRequestData(URL, "GET");355
FileStream fs = new FileStream(fileName, FileMode.Create);356
SaveNetworkStream(fs, true);357
fs.Close();358
fs = null;359
}360

361

/**////<summary>362
///向服务器发送请求363
///</summary>364
///<param name="URL">请求地址</param>365
///<param name="method">POST或GET</param>366
///<param name="showProgress">是否显示上传进度</param>367
private void SendRequestData(string URL, string method, bool showProgress)368

{369
clientSocket = new TcpClient();370
Uri URI = new Uri(URL);371
clientSocket.Connect(URI.Host, URI.Port);372

373
requestHeaders.Add("Host", URI.Host);374
byte[] request = GetRequestHeaders(method + " " + URI.PathAndQuery + " HTTP/1.1");375
clientSocket.Client.Send(request);376

377
//若有实体内容就发送它378
if (postStream != null)379

{380
byte[] buffer = new byte[SEND_BUFFER_SIZE];381
int count = 0;382
Stream sm = clientSocket.GetStream();383
postStream.Position = 0;384

385
UploadEventArgs e = new UploadEventArgs();386
e.totalBytes = postStream.Length;387
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();//计时器388
timer.Start();389
do390

{391
//如果取消就推出392

if (isCanceled)
{ break; }393

394
//读取要发送的数据395
count = postStream.Read(buffer, 0, buffer.Length);396
//发送到服务器397
sm.Write(buffer, 0, count);398

399
//是否显示进度400
if (showProgress)401

{402
//触发事件403
e.bytesSent += count;404
e.sendProgress = (double)e.bytesSent / (double)e.totalBytes;405
double t = timer.ElapsedMilliseconds / 1000;406
t = t <= 0 ? 1 : t;407
e.sendSpeed = (double)e.bytesSent / t;408

if (UploadProgressChanged != null)
{ UploadProgressChanged(this, e); }409
}410

411
} while (count > 0);412
timer.Stop();413
postStream.Close();414
//postStream.Dispose();415
postStream = null;416

417
}//end if418

419
}420

421

/**////<summary>422
///向服务器发送请求423
///</summary>424
///<param name="URL">请求URL地址</param>425
///<param name="method">POST或GET</param>426
private void SendRequestData(string URL, string method)427

{428
SendRequestData(URL, method, false);429
}430

431

432

/**////<summary>433
///获取请求头字节数组434
///</summary>435
///<param name="request">POST或GET请求</param>436
///<returns>请求头字节数组</returns>437
private byte[] GetRequestHeaders(string request)438

{439
requestHeaders.Add("Accept", "*/*");440
requestHeaders.Add("Accept-Language", "zh-cn");441
requestHeaders.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)");442

443
string headers = request + "\r\n";444

445
foreach (string key in requestHeaders)446

{447
headers += key + ":" + requestHeaders[key] + "\r\n";448
}449

450
//有Cookie就带上Cookie451

if (cookie != "")
{ headers += "Cookie:" + cookie + "\r\n"; }452

453
//空行,请求头结束454
headers += "\r\n";455

456
strRequestHeaders = headers;457
requestHeaders.Clear();458
return encoding.GetBytes(headers);459
}460

461

462

463

/**////<summary>464
///获取服务器响应文本465
///</summary>466
///<returns>服务器响应文本</returns>467
private string GetHtml()468

{469
MemoryStream ms = new MemoryStream();470
SaveNetworkStream(ms);//将网络流保存到内存流471
StreamReader sr = new StreamReader(ms, encoding);472
respHtml = sr.ReadToEnd();473
sr.Close();474
ms.Close();475
return respHtml;476
}477

478

/**////<summary>479
///将网络流保存到指定流480
///</summary>481
///<param name="toStream">保存位置</param>482
///<param name="needProgress">是否显示进度</param>483
private void SaveNetworkStream(Stream toStream, bool showProgress)484

{485
//获取要保存的网络流486
NetworkStream NetStream = clientSocket.GetStream();487

488
byte[] buffer = new byte[RECEIVE_BUFFER_SIZE];489
int count = 0, startIndex = 0;490

491
MemoryStream ms = new MemoryStream();492
for (int i = 0; i < 3; i++)493

{494
count = NetStream.Read(buffer, 0, 500);495
ms.Write(buffer, 0, count);496
}497

498

if (ms.Length == 0)
{ NetStream.Close(); throw new Exception("远程服务器没有响应"); }499

500
buffer = ms.GetBuffer();501
count = (int)ms.Length;502

503
GetResponseHeader(buffer, out startIndex);//分析响应,获取响应头和响应实体504
count -= startIndex;505
toStream.Write(buffer, startIndex, count);506

507
DownloadEventArgs e = new DownloadEventArgs();508

509
if (responseHeaders["Content-Length"] != null)510

{ e.totalBytes = long.Parse(responseHeaders["Content-Length"]); }511
else512

{ e.totalBytes = -1; }513

514
//启动计时器515
System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();516
timer.Start();517

518
do519

{520
//如果取消就推出521

if (isCanceled)
{ break; }522

523
//显示下载进度524
if (showProgress)525

{526
e.bytesReceived += count;527
e.ReceiveProgress = (double)e.bytesReceived / (double)e.totalBytes;528

529
byte[] tempBuffer = new byte[count];530
Array.Copy(buffer, startIndex, tempBuffer, 0, count);531
e.receivedBuffer = tempBuffer;532

533
double t = (timer.ElapsedMilliseconds + 0.1) / 1000;534
e.receiveSpeed = (double)e.bytesReceived / t;535

536
startIndex = 0;537

if (DownloadProgressChanged != null)
{ DownloadProgressChanged(this, e); }538
}539

540
//读取网路数据到缓冲区541
count = NetStream.Read(buffer, 0, buffer.Length);542

543
//将缓存区数据保存到指定流544
toStream.Write(buffer, 0, count);545
} while (count > 0);546

547
timer.Stop();//关闭计时器548

549
if (responseHeaders["Content-Length"] != null)550

{551
toStream.SetLength(long.Parse(responseHeaders["Content-Length"]));552
}553
//else554
//{555
// toStream.SetLength(toStream.Length);556
// responseHeaders.Add("Content-Length", toStream.Length.ToString());//添加响应标头557
//}558

559
toStream.Position = 0;560

561
//关闭网络流和网络连接562
NetStream.Close();563
clientSocket.Close();564
}565

566

567

/**////<summary>568
///将网络流保存到指定流569
///</summary>570
///<param name="toStream">保存位置</param>571
private void SaveNetworkStream(Stream toStream)572

{573
SaveNetworkStream(toStream, false);574
}575

576

577

578

/**////<summary>579
///分析响应流,去掉响应头580
///</summary>581
///<param name="buffer"></param>582
private void GetResponseHeader(byte[] buffer, out int startIndex)583

{584
responseHeaders.Clear();585
string html = encoding.GetString(buffer);586
StringReader sr = new StringReader(html);587
588
int start = html.IndexOf("\r\n\r\n") + 4;//找到空行位置589
strResponseHeaders = html.Substring(0, start);//获取响应头文本590
591
//获取响应状态码592
//593
if (sr.Peek() > -1)594

{595
//读第一行字符串596
string line = sr.ReadLine();597
598
//分析此行字符串,获取服务器响应状态码599
Match M = RE.Match(line, @"\d\d\d");600
if (M.Success)601

{602
statusCode = int.Parse(M.Value);603
}604
}605
606
//获取响应头607
//608
while (sr.Peek() > -1)609

{610
//读一行字符串611
string line = sr.ReadLine();612
613
//若非空行614
if (line != "")615

{616
//分析此行字符串,获取响应标头617
Match M = RE.Match(line, "([^:]+):(.+)");618
if (M.Success)619

{620
try621

{ //添加响应标头到集合622
responseHeaders.Add(M.Groups[1].Value.Trim(), M.Groups[2].Value.Trim());623
}624
catch625

{ }626
627
628
//获取Cookie629
if (M.Groups[1].Value == "Set-Cookie")630

{631
M = RE.Match(M.Groups[2].Value, "[^=]+=[^;]+");632
cookie += M.Value.Trim() + ";";633
}634
}635
636
}637
//若是空行,代表响应头结束响应实体开始。(响应头和响应实体间用一空行隔开)638
else639

{640
//如果响应头中没有实体大小标头,尝试读响应实体第一行获取实体大小641
if (responseHeaders["Content-Length"] == null && sr.Peek() > -1)642

{643
//读响应实体第一行644
line = sr.ReadLine();645
646
//分析此行看是否包含实体大小647
Match M = RE.Match(line, "~[0-9a-fA-F]{1,15}");648
649
if (M.Success)650

{651
//将16进制的实体大小字符串转换为10进制652
int length = int.Parse(M.Value, System.Globalization.NumberStyles.AllowHexSpecifier);653
responseHeaders.Add("Content-Length", length.ToString());//添加响应标头654
strResponseHeaders += M.Value + "\r\n";655
}656
}657
break;//跳出循环 658
}//End If659
}//End While660
661
sr.Close();662
663
//实体开始索引664
startIndex = encoding.GetBytes(strResponseHeaders).Length;665
}666

667

668

/**////<summary>669
///取消上传或下载,要继续开始请调用Start方法670
///</summary>671
public void Cancel()672

{673
isCanceled = true;674
}675

676

/**////<summary>677
///启动上传或下载,要取消请调用Cancel方法678
///</summary>679
public void Start()680

{681
isCanceled = false;682
}683

684
//*************************************************************685
//以下为属性686
//*************************************************************687

688

/**////<summary>689
///获取或设置请求头690
///</summary>691
public WebHeaderCollection RequestHeaders692

{693

set
{ requestHeaders = value; }694

get
{ return requestHeaders; }695
}696

697

/**////<summary>698
///获取响应头集合699
///</summary>700
public WebHeaderCollection ResponseHeaders701

{702

get
{ return responseHeaders; }703
}704

705

/**////<summary>706
///获取请求头文本707
///</summary>708
public string StrRequestHeaders709

{710

get
{ return strRequestHeaders; }711
}712

713

/**////<summary>714
///获取响应头文本715
///</summary>716
public string StrResponseHeaders717

{718

get
{ return strResponseHeaders; }719
}720

721

/**////<summary>722
///获取或设置Cookie723
///</summary>724
public string Cookie725

{726

set
{ cookie = value; }727

get
{ return cookie; }728
}729

730

/**////<summary>731
///获取或设置编码方式(默认为系统默认编码方式)732
///</summary>733
public Encoding Encoding734

{735

set
{ encoding = value; }736

get
{ return encoding; }737
}738

739

/**////<summary>740
///获取服务器响应文本741
///</summary>742
public string RespHtml743

{744

get
{ return respHtml; }745
}746

747

748

/**////<summary>749
///获取服务器响应状态码750
///</summary>751
public int StatusCode752

{753

get
{ return statusCode; }754
}755
}756
}757

浙公网安备 33010602011771号