C# 使用 Socket 实现 http 协议全功能版

通过对比测试,作者发现使用 Socket 直接处理 HTTP 请求在获取文本内容时,效率可比 HttpWebRequest 提升 30%-40%。代码实现了基本的 HTTP 和 HTTPS 请求,支持 gzip 解压及分块传输。然而,考虑到更多复杂情况,Socket 方案的效率可能不及 HttpWebRequest。文章分享了源码并邀请读者讨论技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     有人说用 Socket 请求 http 服务效率要比 HttpWebRequest 高很多, 但是又没有提供源码或者对比测试结果. 我对此很好奇, 到底能差多少? 所以决定自己写个类实现 Socket 请求 http 的功能.

  下面的代码实现了基本的 http ,https 请求, 支持 gzip 解压, 分块传输.

  经本人多次试验, 得出如下结论:

  如果仅用 Socket 获取文本类型的内容, 且不考虑分块传输的情况, 那么 Socket 方式可比 HttpWebRequest 方式效率高 30%-40%.

  如果考虑更多因素,需要做更多处理, 所以多数时候效率不如 HttpWebRequest, 当然与我写的代码效率有很大关系.

  本文首发地址 http://blog.itnmg.net/socket-http/

  欢迎共同探讨技术问题,提供建议, 请留言,我会尽快回复.

  1 /* Name:    Socket 实现 http 协议全功能版
  2  * Version: v0.6
  3  * Description: 此版本实现了 http 及 https 的 get 或 post 访问, 自动处理301,302跳转, 支持 gzip 解压, 分块传输.
  4  *                支持的操作: 获取文本,图片,文件形式的内容.
  5  * 使用方法:    new HttpWebSocket(); 调用实例的 Get.... 方法.
  6  * 声明:        本代码仅做技术探讨,可任意转载,请勿用于商业用途.
  7  * 本人博客:    http://blog.itnmg.net   http://www.cnblogs.com/lhg-net
  8  * 创建日期:    2013-01-15
  9  * 修订日期:    2013-06-03
 10  */
 11 using System;
 12 using System.Collections.Generic;
 13 using System.Net;
 14 using System.Net.Sockets;
 15 using System.Net.Security;
 16 using System.Text;
 17 using System.Text.RegularExpressions;
 18 using System.IO;
 19 using System.IO.Compression;
 20 using System.Web;
 21 using System.Drawing;
 22 using System.Security.Cryptography.X509Certificates;
 23 
 24 namespace ExtLibrary.Net
 25 {
 26     class HttpWebSocket
 27     {
 28         /// <summary>
 29         /// 获取或设置请求与回应的超时时间,默认3秒.
 30         /// </summary>
 31         public int TimeOut
 32         {
 33             get;
 34             set;
 35         }
 36 
 37         /// <summary>
 38         /// 获取或设置请求cookie
 39         /// </summary>
 40         public List<string> Cookies
 41         {
 42             get;
 43             set;
 44         }
 45 
 46         /// <summary>
 47         /// 获取请求返回的 HTTP 头部内容
 48         /// </summary>
 49         public HttpHeader HttpHeaders
 50         {
 51             get;
 52             internal set;
 53         }
 54 
 55         /// <summary>
 56         /// 获取或设置错误信息分隔符
 57         /// </summary>
 58         private string ErrorMessageSeparate;
 59 
 60 
 61 
 62         public HttpWebSocket()
 63         {
 64             this.TimeOut = 3;
 65             this.Cookies = new List<string>();
 66             this.ErrorMessageSeparate = ";;";
 67             this.HttpHeaders = new HttpHeader();
 68         }
 69 
 70 
 71 
 72         /// <summary>
 73         /// get或post方式请求一个 http 或 https 地址.使用 Socket 方式
 74         /// </summary>
 75         /// <param name="url">请求绝对地址</param>
 76         /// <param name="referer">请求来源地址,可为空</param>
 77         /// <param name="postData">post请求参数. 设置空值为get方式请求</param>
 78         /// <returns>返回图像</returns>
 79         public Image GetImageUseSocket( string url, string referer, string postData = null )
 80         {
 81             Image result = null;
 82             MemoryStream ms = this.GetSocketResult( url, referer, postData );
 83 
 84             try
 85             {
 86                 if ( ms != null )
 87                 {
 88                     result = Image.FromStream( ms );
 89                 }
 90             }
 91             catch ( Exception e )
 92             {
 93                 string ss = e.Message;
 94             }
 95 
 96             return result;
 97         }
 98 
 99         /// <summary>
100         /// get或post方式请求一个 http 或 https 地址.使用 Socket 方式
101         /// </summary>
102         /// <param name="url">请求绝对地址</param>
103         /// <param name="postData">post请求参数. 设置空值为get方式请求</param>
104         /// <returns>返回 html 内容,如果发生异常将返回上次http状态码及异常信息</returns>
105         public string GetHtmlUseSocket( string url, string postData = null )
106         {
107             return this.GetHtmlUseSocket( url, null, postData );
108         }
109 
110         /// <summary>
111         /// get或post方式请求一个 http 或 https 地址.使用 Socket 方式
112         /// </summary>
113         /// <param name="url">请求绝对地址</param>
114         /// <param name="referer">请求来源地址,可为空</param>
115         /// <param name="postData">post请求参数. 设置空值为get方式请求</param>
116         /// <returns>返回 html 内容,如果发生异常将返回上次http状态码及异常信息</returns>
117         public string GetHtmlUseSocket( string url, string referer, string postData = null )
118         {
119             string result = string.Empty;
120 
121             try
122             {
123                 MemoryStream ms = this.GetSocketResult( url, referer, postData );
124 
125                 if ( ms != null )
126                 {
127                     result = Encoding.GetEncoding( string.IsNullOrWhiteSpace( this.HttpHeaders.Charset ) ? "UTF-8" : this.HttpHeaders.Charset ).GetString( ms.ToArray() );
128                 }
129             }
130             catch ( SocketException se )
131             {
132                 result = this.HttpHeaders.ResponseStatusCode + this.ErrorMessageSeparate + se.ErrorCode.ToString() + this.ErrorMessageSeparate + se.SocketErrorCode.ToString( "G" ) + this.ErrorMessageSeparate + se.Message;
133             }
134             catch ( Exception e )
135             {
136                 result = this.HttpHeaders.ResponseStatusCode + this.ErrorMessageSeparate + e.Message;
137             }
138 
139             return result;
140         }
141 
142         /// <summary>
143         /// get或post方式请求一个 http 或 https 地址.
144         /// </summary>
145         /// <param name="url">请求绝对地址</param>
146         /// <param name="referer">请求来源地址,可为空</param>
147         /// <param name="postData">post请求参数. 设置空值为get方式请求</param>
148         /// <returns>返回的已解压的数据内容</returns>
149         private MemoryStream GetSocketResult( string url, string referer, string postData )
150         {
151             if ( string.IsNullOrWhiteSpace( url ) )
152             {
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值