WebClient.cs封装

  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. * *文件名:HttpProc.cs
  13. * *创建人:kenter
  14. * *日 期:2010.02.23 修改
  15. * *描 述:实现HTTP协议中的GET、POST请求
  16. * *使 用:HttpProc.WebClient client = new HttpProc.WebClient();
  17. client.Encoding = System.Text.Encoding.Default;//默认编码方式,根据需要设置其他类型
  18. client.OpenRead("http://www.baidu.com");//普通get请求
  19. MessageBox.Show(client.RespHtml);//获取返回的网页源代码
  20. client.DownloadFile("http://www.codepub.com/upload/163album.rar",@"C:\163album.rar");//下载文件
  21. client.OpenRead("http://passport.baidu.com/?login","username=zhangsan&password=123456");//提交表单,此处是登录百度的示例
  22. client.UploadFile("http://hiup.baidu.com/zhangsan/upload", @"file1=D:\1.mp3");//上传文件
  23. client.UploadFile("http://hiup.baidu.com/zhangsan/upload", "folder=myfolder&size=4003550",@"file1=D:\1.mp3");//提交含文本域和文件域的表单
  24. *****************************************************************************************************************************************************/
  25. namespace HttpProc
  26. {
  27. ///<summary>
  28. ///上传事件委托
  29. ///</summary>
  30. ///<param name="sender"></param>
  31. ///<param name="e"></param>
  32. public delegate void WebClientUploadEvent(object sender, HttpProc.UploadEventArgs e);
  33. ///<summary>
  34. ///下载事件委托
  35. ///</summary>
  36. ///<param name="sender"></param>
  37. ///<param name="e"></param>
  38. public delegate void WebClientDownloadEvent(object sender, HttpProc.DownloadEventArgs e);
  39. ///<summary>
  40. ///上传事件参数
  41. ///</summary>
  42. public struct UploadEventArgs
  43. {
  44. ///<summary>
  45. ///上传数据总大小
  46. ///</summary>
  47. public long totalBytes;
  48. ///<summary>
  49. ///已发数据大小
  50. ///</summary>
  51. public long bytesSent;
  52. ///<summary>
  53. ///发送进度(0-1)
  54. ///</summary>
  55. public double sendProgress;
  56. ///<summary>
  57. ///发送速度Bytes/s
  58. ///</summary>
  59. public double sendSpeed;
  60. }
  61. ///<summary>
  62. ///下载事件参数
  63. ///</summary>
  64. public struct DownloadEventArgs
  65. {
  66. ///<summary>
  67. ///下载数据总大小
  68. ///</summary>
  69. public long totalBytes;
  70. ///<summary>
  71. ///已接收数据大小
  72. ///</summary>
  73. public long bytesReceived;
  74. ///<summary>
  75. ///接收数据进度(0-1)
  76. ///</summary>
  77. public double ReceiveProgress;
  78. ///<summary>
  79. ///当前缓冲区数据
  80. ///</summary>
  81. public byte[] receivedBuffer;
  82. ///<summary>
  83. ///接收速度Bytes/s
  84. ///</summary>
  85. public double receiveSpeed;
  86. }
  87. ///<summary>
  88. ///实现向WEB服务器发送和接收数据
  89. ///</summary>
  90. public class WebClient
  91. {
  92. private WebHeaderCollection requestHeaders, responseHeaders;
  93. private TcpClient clientSocket;
  94. private MemoryStream postStream;
  95. private Encoding encoding = Encoding.Default;
  96. private const string BOUNDARY = "--HEDAODE--";
  97. private const int SEND_BUFFER_SIZE = 10245;
  98. private const int RECEIVE_BUFFER_SIZE = 10245;
  99. private string cookie = "";
  100. private string respHtml = "";
  101. private string strRequestHeaders = "";
  102. private string strResponseHeaders = "";
  103. private int statusCode = 0;
  104. private bool isCanceled = false;
  105. public event WebClientUploadEvent UploadProgressChanged;
  106. public event WebClientDownloadEvent DownloadProgressChanged;
  107. ///<summary>
  108. ///初始化WebClient类
  109. ///</summary>
  110. public WebClient()
  111. {
  112. responseHeaders = new WebHeaderCollection();
  113. requestHeaders = new WebHeaderCollection();
  114. }
  115. /// <summary>
  116. /// 获得字符串中开始和结束字符串中间得值
  117. /// </summary>
  118. /// <param name="str"></param>
  119. /// <param name="s">开始</param>
  120. /// <param name="e">结束</param>
  121. /// <returns></returns>
  122. public string gethtmlContent(string str, string s, string e)
  123. {
  124. Regex rg = new Regex("(?<=(" + s + "))[.\\s\\S]*?(?=(" + e + "))", RegexOptions.Multiline | RegexOptions.Singleline);
  125. return rg.Match(str).Value;
  126. }
  127. /// <summary>
  128. /// 过滤HTML字符
  129. /// </summary>
  130. /// <param name="source"></param>
  131. /// <returns></returns>
  132. public string htmlConvert(string source)
  133. {
  134. string result;
  135. //remove line breaks,tabs
  136. result = source.Replace("\r", " ");
  137. result = result.Replace("\n", " ");
  138. result = result.Replace("\t", " ");
  139. //remove the header
  140. result = Regex.Replace(result, "(<head>).*(</head>)", string.Empty, RegexOptions.IgnoreCase);
  141. result = Regex.Replace(result, @"<( )*script([^>])*>", "<script>", RegexOptions.IgnoreCase);
  142. result = Regex.Replace(result, @"(<script>).*(</script>)", string.Empty, RegexOptions.IgnoreCase);
  143. //remove all styles
  144. result = Regex.Replace(result, @"<( )*style([^>])*>", "<style>", RegexOptions.IgnoreCase); //clearing attributes
  145. result = Regex.Replace(result, "(<style>).*(</style>)", string.Empty, RegexOptions.IgnoreCase);
  146. //insert tabs in spaces of <td> tags
  147. result = Regex.Replace(result, @"<( )*td([^>])*>", " ", RegexOptions.IgnoreCase);
  148. //insert line breaks in places of <br> and <li> tags
  149. result = Regex.Replace(result, @"<( )*br( )*>", "\r", RegexOptions.IgnoreCase);
  150. result = Regex.Replace(result, @"<( )*li( )*>", "\r", RegexOptions.IgnoreCase);
  151. //insert line paragraphs in places of <tr> and <p> tags
  152. result = Regex.Replace(result, @"<( )*tr([^>])*>", "\r\r", RegexOptions.IgnoreCase);
  153. result = Regex.Replace(result, @"<( )*p([^>])*>", "\r\r", RegexOptions.IgnoreCase);
  154. //remove anything thats enclosed inside < >
  155. result = Regex.Replace(result, @"<[^>]*>", string.Empty, RegexOptions.IgnoreCase);
  156. //replace special characters:
  157. result = Regex.Replace(result, @"&amp;", "&", RegexOptions.IgnoreCase);
  158. result = Regex.Replace(result, @"&nbsp;", " ", RegexOptions.IgnoreCase);
  159. result = Regex.Replace(result, @"&lt;", "<", RegexOptions.IgnoreCase);
  160. result = Regex.Replace(result, @"&gt;", ">", RegexOptions.IgnoreCase);
  161. result = Regex.Replace(result, @"&(.{2,6});", string.Empty, RegexOptions.IgnoreCase);
  162. //remove extra line breaks and tabs
  163. result = Regex.Replace(result, @" ( )+", " ");
  164. result = Regex.Replace(result, "(\r)( )+(\r)", "\r\r");
  165. result = Regex.Replace(result, @"(\r\r)+", "\r\n");
  166. return result;
  167. }
  168. ///<summary>
  169. ///读取指定URL的文本
  170. ///</summary>
  171. ///<param name="URL">请求的地址</param>
  172. ///<returns>服务器响应文本</returns>
  173. public string OpenRead(string URL)
  174. {
  175. requestHeaders.Add("Connection", "close");
  176. SendRequestData(URL, "GET");
  177. return GetHtml();
  178. }
  179. //解决证书过期无法访问的问题
  180. class CertPolicy : ICertificatePolicy
  181. {
  182. public bool CheckValidationResult(ServicePoint srvpt, X509Certificate cert, WebRequest req, int certprb)
  183. { return true; }
  184. }
  185. ///<summary>
  186. ///采用https协议访问网络
  187. ///</summary>
  188. ///<param name="URL">url地址</param>
  189. ///<param name="strPostdata">发送的数据</param>
  190. ///<returns></returns>
  191. public string OpenReadWithHttps(string URL, string strPostdata)
  192. {
  193. ServicePointManager.CertificatePolicy = new CertPolicy();
  194. HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
  195. request.CookieContainer = new CookieContainer();
  196. request.Method = "POST";
  197. request.Accept = "*/*";
  198. request.ContentType = "application/x-www-form-urlencoded";
  199. byte[] buffer = this.encoding.GetBytes(strPostdata);
  200. request.ContentLength = buffer.Length;
  201. request.GetRequestStream().Write(buffer, 0, buffer.Length);
  202. HttpWebResponse response = (HttpWebResponse)request.GetResponse();
  203. StreamReader reader = new StreamReader(response.GetResponseStream(), encoding);
  204. this.respHtml = reader.ReadToEnd();
  205. foreach (System.Net.Cookie ck in response.Cookies)
  206. {
  207. this.cookie += ck.Name + "=" + ck.Value + ";";
  208. }
  209. reader.Close();
  210. return respHtml;
  211. }
  212. ///<summary>
  213. ///读取指定URL的文本
  214. ///</summary>
  215. ///<param name="URL">请求的地址</param>
  216. ///<param name="postData">向服务器发送的文本数据</param>
  217. ///<returns>服务器响应文本</returns>
  218. public string OpenRead(string URL, string postData)
  219. {
  220. byte[] sendBytes = encoding.GetBytes(postData);
  221. postStream = new MemoryStream();
  222. postStream.Write(sendBytes, 0, sendBytes.Length);
  223. requestHeaders.Add("Content-Length", postStream.Length.ToString());
  224. requestHeaders.Add("Content-Type", "application/x-www-form-urlencoded");
  225. requestHeaders.Add("Connection", "close");
  226. SendRequestData(URL, "POST");
  227. return GetHtml();
  228. }
  229. ///<summary>
  230. ///读取指定URL的流
  231. ///</summary>
  232. ///<param name="URL">请求的地址</param>
  233. ///<param name="postData">向服务器发送的数据</param>
  234. ///<returns>服务器响应流</returns>
  235. public Stream GetStream(string URL, string postData)
  236. {
  237. byte[] sendBytes = encoding.GetBytes(postData);
  238. postStream = new MemoryStream();
  239. postStream.Write(sendBytes, 0, sendBytes.Length);
  240. requestHeaders.Add("Content-Length", postStream.Length.ToString());
  241. requestHeaders.Add("Content-Type", "application/x-www-form-urlencoded");
  242. requestHeaders.Add("Connection", "close");
  243. SendRequestData(URL, "POST");
  244. MemoryStream ms = new MemoryStream();
  245. SaveNetworkStream(ms);
  246. return ms;
  247. }
  248. ///<summary>
  249. ///上传文件到服务器
  250. ///</summary>
  251. ///<param name="URL">请求的地址</param>
  252. ///<param name="fileField">文件域(格式如:file1=C:\test.mp3&file2=C:\test.jpg)</param>
  253. ///<returns>服务器响应文本</returns>
  254. public string UploadFile(string URL, string fileField)
  255. {
  256. return UploadFile(URL, "", fileField);
  257. }
  258. ///<summary>
  259. ///上传文件和数据到服务器
  260. ///</summary>
  261. ///<param name="URL">请求地址</param>
  262. ///<param name="textField">文本域(格式为:name1=value1&name2=value2)</param>
  263. ///<param name="fileField">文件域(格式如:file1=C:\test.mp3&file2=C:\test.jpg)</param>
  264. ///<returns>服务器响应文本</returns>
  265. public string UploadFile(string URL, string textField, string fileField)
  266. {
  267. postStream = new MemoryStream();
  268. if (textField != "" && fileField != "")
  269. {
  270. WriteTextField(textField);
  271. WriteFileField(fileField);
  272. }
  273. else if (fileField != "")
  274. {
  275. WriteFileField(fileField);
  276. }
  277. else if (textField != "")
  278. {
  279. WriteTextField(textField);
  280. }
  281. else
  282. throw new Exception("文本域和文件域不能同时为空。");
  283. //写入结束标记
  284. byte[] buffer = encoding.GetBytes("--" + BOUNDARY + "--\r\n");
  285. postStream.Write(buffer, 0, buffer.Length);
  286. //添加请求标头
  287. requestHeaders.Add("Content-Length", postStream.Length.ToString());
  288. requestHeaders.Add("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
  289. requestHeaders.Add("Connection", "Keep-Alive");
  290. //发送请求数据
  291. SendRequestData(URL, "POST", true);
  292. //返回响应文本
  293. return GetHtml();
  294. }
  295. ///<summary>
  296. ///分析文本域,添加到请求流
  297. ///</summary>
  298. ///<param name="textField">文本域</param>
  299. private void WriteTextField(string textField)
  300. {
  301. string[] strArr = RE.Split(textField, "&");
  302. textField = "";
  303. foreach (string var in strArr)
  304. {
  305. Match M = RE.Match(var, "([^=]+)=(.+)");
  306. textField += "--" + BOUNDARY + "\r\n";
  307. textField += "Content-Disposition: form-data; name=\"" + M.Groups[1].Value + "\"\r\n\r\n" + M.Groups[2].Value + "\r\n";
  308. }
  309. byte[] buffer = encoding.GetBytes(textField);
  310. postStream.Write(buffer, 0, buffer.Length);
  311. }
  312. ///<summary>
  313. ///分析文件域,添加到请求流
  314. ///</summary>
  315. ///<param name="fileField">文件域</param>
  316. private void WriteFileField(string fileField)
  317. {
  318. string filePath = "";
  319. int count = 0;
  320. string[] strArr = RE.Split(fileField, "&");
  321. foreach (string var in strArr)
  322. {
  323. Match M = RE.Match(var, "([^=]+)=(.+)");
  324. filePath = M.Groups[2].Value;
  325. fileField = "--" + BOUNDARY + "\r\n";
  326. fileField += "Content-Disposition: form-data; name=\"" + M.Groups[1].Value + "\"; filename=\"" + Path.GetFileName(filePath) + "\"\r\n";
  327. fileField += "Content-Type: image/jpeg\r\n\r\n";
  328. byte[] buffer = encoding.GetBytes(fileField);
  329. postStream.Write(buffer, 0, buffer.Length);
  330. //添加文件数据
  331. FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  332. buffer = new byte[50000];
  333. do
  334. {
  335. count = fs.Read(buffer, 0, buffer.Length);
  336. postStream.Write(buffer, 0, count);
  337. } while (count > 0);
  338. fs.Close();
  339. fs.Dispose();
  340. fs = null;
  341. buffer = encoding.GetBytes("\r\n");
  342. postStream.Write(buffer, 0, buffer.Length);
  343. }
  344. }
  345. ///<summary>
  346. ///从指定URL下载数据流
  347. ///</summary>
  348. ///<param name="URL">请求地址</param>
  349. ///<returns>数据流</returns>
  350. public Stream DownloadData(string URL)
  351. {
  352. requestHeaders.Add("Connection", "close");
  353. SendRequestData(URL, "GET");
  354. MemoryStream ms = new MemoryStream();
  355. SaveNetworkStream(ms, true);
  356. return ms;
  357. }
  358. ///<summary>
  359. ///从指定URL下载文件
  360. ///</summary>
  361. ///<param name="URL">文件URL地址</param>
  362. ///<param name="fileName">文件保存路径,含文件名(如:C:\test.jpg)</param>
  363. public void DownloadFile(string URL, string fileName)
  364. {
  365. requestHeaders.Add("Connection", "close");
  366. SendRequestData(URL, "GET");
  367. FileStream fs = new FileStream(fileName, FileMode.Create);
  368. SaveNetworkStream(fs, true);
  369. fs.Close();
  370. fs = null;
  371. }
  372. ///<summary>
  373. ///向服务器发送请求
  374. ///</summary>
  375. ///<param name="URL">请求地址</param>
  376. ///<param name="method">POST或GET</param>
  377. ///<param name="showProgress">是否显示上传进度</param>
  378. private void SendRequestData(string URL, string method, bool showProgress)
  379. {
  380. clientSocket = new TcpClient();
  381. Uri URI = new Uri(URL);
  382. clientSocket.Connect(URI.Host, URI.Port);
  383. requestHeaders.Add("Host", URI.Host);
  384. byte[] request = GetRequestHeaders(method + " " + URI.PathAndQuery + " HTTP/1.1");
  385. clientSocket.Client.Send(request);
  386. //若有实体内容就发送它
  387. if (postStream != null)
  388. {
  389. byte[] buffer = new byte[SEND_BUFFER_SIZE];
  390. int count = 0;
  391. Stream sm = clientSocket.GetStream();
  392. postStream.Position = 0;
  393. UploadEventArgs e = new UploadEventArgs();
  394. e.totalBytes = postStream.Length;
  395. System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();//计时器
  396. timer.Start();
  397. do
  398. {
  399. //如果取消就推出
  400. if (isCanceled) { break; }
  401. //读取要发送的数据
  402. count = postStream.Read(buffer, 0, buffer.Length);
  403. //发送到服务器
  404. sm.Write(buffer, 0, count);
  405. //是否显示进度
  406. if (showProgress)
  407. {
  408. //触发事件
  409. e.bytesSent += count;
  410. e.sendProgress = (double)e.bytesSent / (double)e.totalBytes;
  411. double t = timer.ElapsedMilliseconds / 1000;
  412. t = t <= 0 ? 1 : t;
  413. e.sendSpeed = (double)e.bytesSent / t;
  414. if (UploadProgressChanged != null) { UploadProgressChanged(this, e); }
  415. }
  416. } while (count > 0);
  417. timer.Stop();
  418. postStream.Close();
  419. //postStream.Dispose();
  420. postStream = null;
  421. }//end if
  422. }
  423. ///<summary>
  424. ///向服务器发送请求
  425. ///</summary>
  426. ///<param name="URL">请求URL地址</param>
  427. ///<param name="method">POST或GET</param>
  428. private void SendRequestData(string URL, string method)
  429. {
  430. SendRequestData(URL, method, false);
  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. string headers = request + "\r\n";
  443. foreach (string key in requestHeaders)
  444. {
  445. headers += key + ":" + requestHeaders[key] + "\r\n";
  446. }
  447. //有Cookie就带上Cookie
  448. if (cookie != "") { headers += "Cookie:" + cookie + "\r\n"; }
  449. //空行,请求头结束
  450. headers += "\r\n";
  451. strRequestHeaders = headers;
  452. requestHeaders.Clear();
  453. return encoding.GetBytes(headers);
  454. }
  455. ///<summary>
  456. ///获取服务器响应文本
  457. ///</summary>
  458. ///<returns>服务器响应文本</returns>
  459. private string GetHtml()
  460. {
  461. MemoryStream ms = new MemoryStream();
  462. SaveNetworkStream(ms);//将网络流保存到内存流
  463. StreamReader sr = new StreamReader(ms, encoding);
  464. respHtml = sr.ReadToEnd();
  465. sr.Close(); ms.Close();
  466. return respHtml;
  467. }
  468. ///<summary>
  469. ///将网络流保存到指定流
  470. ///</summary>
  471. ///<param name="toStream">保存位置</param>
  472. ///<param name="needProgress">是否显示进度</param>
  473. private void SaveNetworkStream(Stream toStream, bool showProgress)
  474. {
  475. //获取要保存的网络流
  476. NetworkStream NetStream = clientSocket.GetStream();
  477. byte[] buffer = new byte[RECEIVE_BUFFER_SIZE];
  478. int count = 0, startIndex = 0;
  479. MemoryStream ms = new MemoryStream();
  480. for (int i = 0; i < 3; i++)
  481. {
  482. count = NetStream.Read(buffer, 0, 500);
  483. ms.Write(buffer, 0, count);
  484. }
  485. if (ms.Length == 0) { NetStream.Close(); throw new Exception("远程服务器没有响应"); }
  486. buffer = ms.GetBuffer();
  487. count = (int)ms.Length;
  488. GetResponseHeader(buffer, out startIndex);//分析响应,获取响应头和响应实体
  489. count -= startIndex;
  490. toStream.Write(buffer, startIndex, count);
  491. DownloadEventArgs e = new DownloadEventArgs();
  492. if (responseHeaders["Content-Length"] != null)
  493. { e.totalBytes = long.Parse(responseHeaders["Content-Length"]); }
  494. else
  495. { e.totalBytes = -1; }
  496. //启动计时器
  497. System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch();
  498. timer.Start();
  499. do
  500. {
  501. //如果取消就推出
  502. if (isCanceled) { break; }
  503. //显示下载进度
  504. if (showProgress)
  505. {
  506. e.bytesReceived += count;
  507. e.ReceiveProgress = (double)e.bytesReceived / (double)e.totalBytes;
  508. byte[] tempBuffer = new byte[count];
  509. Array.Copy(buffer, startIndex, tempBuffer, 0, count);
  510. e.receivedBuffer = tempBuffer;
  511. double t = (timer.ElapsedMilliseconds + 0.1) / 1000;
  512. e.receiveSpeed = (double)e.bytesReceived / t;
  513. startIndex = 0;
  514. if (DownloadProgressChanged != null) { DownloadProgressChanged(this, e); }
  515. }
  516. //读取网路数据到缓冲区
  517. count = NetStream.Read(buffer, 0, buffer.Length);
  518. //将缓存区数据保存到指定流
  519. toStream.Write(buffer, 0, count);
  520. } while (count > 0);
  521. timer.Stop();//关闭计时器
  522. if (responseHeaders["Content-Length"] != null)
  523. {
  524. toStream.SetLength(long.Parse(responseHeaders["Content-Length"]));
  525. }
  526. //else
  527. //{
  528. // toStream.SetLength(toStream.Length);
  529. // responseHeaders.Add("Content-Length", toStream.Length.ToString());//添加响应标头
  530. //}
  531. toStream.Position = 0;
  532. //关闭网络流和网络连接
  533. NetStream.Close();
  534. clientSocket.Close();
  535. }
  536. ///<summary>
  537. ///将网络流保存到指定流
  538. ///</summary>
  539. ///<param name="toStream">保存位置</param>
  540. private void SaveNetworkStream(Stream toStream)
  541. {
  542. SaveNetworkStream(toStream, false);
  543. }
  544. ///<summary>
  545. ///分析响应流,去掉响应头
  546. ///</summary>
  547. ///<param name="buffer"></param>
  548. private void GetResponseHeader(byte[] buffer, out int startIndex)
  549. {
  550. responseHeaders.Clear();
  551. string html = encoding.GetString(buffer);
  552. StringReader sr = new StringReader(html);
  553. int start = html.IndexOf("\r\n\r\n") + 4;//找到空行位置
  554. strResponseHeaders = html.Substring(0, start);//获取响应头文本
  555. //获取响应状态码
  556. //
  557. if (sr.Peek() > -1)
  558. {
  559. //读第一行字符串
  560. string line = sr.ReadLine();
  561. //分析此行字符串,获取服务器响应状态码
  562. Match M = RE.Match(line, @"\d\d\d");
  563. if (M.Success)
  564. {
  565. statusCode = int.Parse(M.Value);
  566. }
  567. }
  568. //获取响应头
  569. //
  570. while (sr.Peek() > -1)
  571. {
  572. //读一行字符串
  573. string line = sr.ReadLine();
  574. //若非空行
  575. if (line != "")
  576. {
  577. //分析此行字符串,获取响应标头
  578. Match M = RE.Match(line, "([^:]+):(.+)");
  579. if (M.Success)
  580. {
  581. try
  582. { //添加响应标头到集合
  583. responseHeaders.Add(M.Groups[1].Value.Trim(), M.Groups[2].Value.Trim());
  584. }
  585. catch
  586. { }
  587. //获取Cookie
  588. if (M.Groups[1].Value == "Set-Cookie")
  589. {
  590. M = RE.Match(M.Groups[2].Value, "[^=]+=[^;]+");
  591. cookie += M.Value.Trim() + ";";
  592. }
  593. }
  594. }
  595. //若是空行,代表响应头结束响应实体开始。(响应头和响应实体间用一空行隔开)
  596. else
  597. {
  598. //如果响应头中没有实体大小标头,尝试读响应实体第一行获取实体大小
  599. if (responseHeaders["Content-Length"] == null && sr.Peek() > -1)
  600. {
  601. //读响应实体第一行
  602. line = sr.ReadLine();
  603. //分析此行看是否包含实体大小
  604. Match M = RE.Match(line, "~[0-9a-fA-F]{1,15}");
  605. if (M.Success)
  606. {
  607. //将16进制的实体大小字符串转换为10进制
  608. int length = int.Parse(M.Value, System.Globalization.NumberStyles.AllowHexSpecifier);
  609. responseHeaders.Add("Content-Length", length.ToString());//添加响应标头
  610. strResponseHeaders += M.Value + "\r\n";
  611. }
  612. }
  613. break;//跳出循环
  614. }//End If
  615. }//End While
  616. sr.Close();
  617. //实体开始索引
  618. startIndex = encoding.GetBytes(strResponseHeaders).Length;
  619. }
  620. ///<summary>
  621. ///取消上传或下载,要继续开始请调用Start方法
  622. ///</summary>
  623. public void Cancel()
  624. {
  625. isCanceled = true;
  626. }
  627. ///<summary>
  628. ///启动上传或下载,要取消请调用Cancel方法
  629. ///</summary>
  630. public void Start()
  631. {
  632. isCanceled = false;
  633. }
  634. //*************************************************************
  635. //以下为属性
  636. //*************************************************************
  637. ///<summary>
  638. ///获取或设置请求头
  639. ///</summary>
  640. public WebHeaderCollection RequestHeaders
  641. {
  642. set { requestHeaders = value; }
  643. get { return requestHeaders; }
  644. }
  645. ///<summary>
  646. ///获取响应头集合
  647. ///</summary>
  648. public WebHeaderCollection ResponseHeaders
  649. {
  650. get { return responseHeaders; }
  651. }
  652. ///<summary>
  653. ///获取请求头文本
  654. ///</summary>
  655. public string StrRequestHeaders
  656. {
  657. get { return strRequestHeaders; }
  658. }
  659. ///<summary>
  660. ///获取响应头文本
  661. ///</summary>
  662. public string StrResponseHeaders
  663. {
  664. get { return strResponseHeaders; }
  665. }
  666. ///<summary>
  667. ///获取或设置Cookie
  668. ///</summary>
  669. public string Cookie
  670. {
  671. set { cookie = value; }
  672. get { return cookie; }
  673. }
  674. ///<summary>
  675. ///获取或设置编码方式(默认为系统默认编码方式)
  676. ///</summary>
  677. public Encoding Encoding
  678. {
  679. set { encoding = value; }
  680. get { return encoding; }
  681. }
  682. ///<summary>
  683. ///获取服务器响应文本
  684. ///</summary>
  685. public string RespHtml
  686. {
  687. get { return respHtml; }
  688. }
  689. ///<summary>
  690. ///获取服务器响应状态码
  691. ///</summary>
  692. public int StatusCode
  693. {
  694. get { return statusCode; }
  695. }
  696. }
  697. }  
大部分转载 小部分自写
原文地址:https://www.cnblogs.com/8586/p/2429564.html