ImageVerifierCode 换一换
格式:DOCX , 页数:22 ,大小:20.04KB ,
资源ID:8009136      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8009136.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(粗糙的C#版HTTP代理.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

粗糙的C#版HTTP代理.docx

1、粗糙的C#版HTTP代理粗糙的C#版HTTP代理 2008-8-5 0:38:21 粗糙的C#版HTTP代理说说这段代码的问题吧。首先是字符串切割的问题,要将客户端提交过来的GET,POST等原始请求切割,分离出主机名,端口,URL等数据。这里用正则匹配是最好的,遗憾的是我不擅长此道,所以使用了手动切割的办法,很笨重繁琐,但是毕竟它工作得很好。第二个问题是Keep-Alive的问题,这里我没有处理好。最开始我在http proxy里面修改客户端请求,强行将keep-alive修改为close,但是发现在某些站点的时候会出错。于是使用了类似select的方法读取数据,直到超时关闭两端的连接。我猜

2、测,这里如果解析content-length会更好,但是略微繁琐了点,还是等我仔细阅读下RFC再看怎么修改吧。第三个是CONNECT方法的问题,这个到很简单,转发数据就行了,因此是这个代码中写得最好的一部分,用来登陆QQ还是不错的。 说实话,我不喜欢HTTP这种太宽松的协议,感觉灵活得让我难以把握。直接看代码吧,我加了很多debug信息,真的要用就去掉好了。调用这个类很简单,看main函数的实现就好了。为了方便贴代码,我写的时候就把三个类写到一个文件里面去了。顺便要说的是,虽然有类,但是没有任何面向对象的东西这也再次证明,其实我算不上一个程序员,最多是个代码爱好者。 using System;

3、 using System.Net; using System.Net.Sockets; using System.Text; using System.IO; using System.Threading; using System.Collections; namespace HttpProxy public class HttpProxy int ProxyPort; / / 代理服务器入口类构造函数 / / Http Proxy监听的端口 public HttpProxy( int Port) ProxyPort = Port; / / 启动Http代理服务器 / public voi

4、d Start( ) TcpListener tcplistener = null; try / 开始监听端口 tcplistener = new TcpListener(Dns.GetHostAddresses(Dns.GetHostName()0, ProxyPort); tcplistener.Start(); Console.WriteLine(侦听端口号: + ProxyPort.ToString(); catch (Exception e) Console.WriteLine(启动代理服务器失败: + e.Message); while (true) try / 接受客户端连接 S

5、ocket socket = tcplistener.AcceptSocket(); HttpSession Session = new HttpSession(socket); / 启动新线程,处理连接 Thread thread = new Thread(new ThreadStart(Session.Start); thread.Start(); catch( Exception e ) Console.WriteLine(接受客户端连接异常: + e.Message ); public class HttpSession / 客户端socket Socket ClientSocket;

6、 / 设定编码 Encoding ASCII = Encoding.ASCII; / / 构造函数 / / 客户端socket public HttpSession(Socket socket) this.ClientSocket = socket; public void Start() / 客户端缓冲区,读取客户端命令 Byte ReadBuff = new byte1024 * 10; try int Length = ClientSocket.Receive(ReadBuff); / 没有读到数据 if (0 = Length) Console.WriteLine(从客户端读取命令错误

7、); ClientSocket.Shutdown(SocketShutdown.Both); ClientSocket.Close(); return; / 读取出现异常 catch (Exception e) Console.WriteLine(读取客户端异常: + e.Message); / 来自客户端的HTTP请求字符串 string ClientMsg = ASCII.GetString(ReadBuff); / 根据rnrn截取请求行 string Line = ClientMsg.Substring(0, ClientMsg.IndexOf(rn); string CmdArray

8、 = Line.Split( ); / GET:80/index.php HTTP/1 / CONNECT :443 HTTP/1 string Cmd = CmdArray0; string RawUrl = CmdArray1; Console.WriteLine(原始请求: , Line); / CONNECT请求 if (Cmd = CONNECT) DoConnect(RawUrl); / GET,POST和其他 else DoOther(RawUrl, ClientMsg); / / 处理CONNECT命令,此处作用是支持QQ,MSN,以及多级代理串联等 / / private v

9、oid DoConnect( string RawUrl ) string Args = RawUrl.Split( : ); string Host = Args0; int Port = int.Parse(Args1); Socket ServerSocket = null; try IPAddress IpList = Dns.GetHostEntry(Host).AddressList; Console.WriteLine(尝试连接:, IpList0, Port); ServerSocket = new Socket(AddressFamily.InterNetwork, Sock

10、etType.Stream, ProtocolType.Tcp); ServerSocket.Connect(IpList0, Port); catch (Exception e) Console.WriteLine(连接真实服务器异常: + e.Message); / 连接真实服务器成功 if (ServerSocket.Connected) ClientSocket.Send( ASCII.GetBytes(HTTP/0 200 Connection establishedrnrn) ); else ClientSocket.Shutdown(SocketShutdown.Both); C

11、lientSocket.Close(); / 开始转发数据 ForwardTcpData(ClientSocket, ServerSocket); / / 处理GET,POST等命令。使用了POLL,在代理服务器中强制去掉了Keep-Alive能力 / / / public void DoOther(string RawUrl, string ClientMsg) RawUrl = RawUrl.Substring(0 + http:/.Length); int Port; string Host; string Url; / 下面是分割处理请求,此处应该用正则匹配,不过我不擅长,因此手动切割

12、,_! int index1 = RawUrl.IndexOf(:); / 没有端口 if (index1 = -1) Port = 80; int index2 = RawUrl.IndexOf(/); / 没有目录 if (index2 = -1) Host = RawUrl; Url = /; else Host = RawUrl.Substring(0, index2); Url = RawUrl.Substring(index2); else int index2 = RawUrl.IndexOf(/); / 没有目录 if (index2 = -1) Host = RawUrl.S

13、ubstring(0, index1); Port = IntParse(RawUrl.Substring(index1 + 1); Url = /; else / /出现在:之前,则说明:后面的不是端口 if (index2 index1) Host = RawUrl.Substring(0, index2); Port = 80; else Host = RawUrl.Substring(0, index1); Port = IntParse(RawUrl.Substring(index1 + 1, index2 - index1 - 1); Url = RawUrl.Substring(

14、index2); Console.WriteLine(Host is:, Port is:, Url is:, Host, Port, Url); IPAddress address = null; try IPHostEntry IPHost = Dns.GetHostEntry(Host); address = IPHost.AddressList; Console.WriteLine(Web服务器IP地址: + address0); catch( Exception e ) Console.WriteLine( 解析服务器地址异常: + e.Message ); Socket IPsoc

15、ket = null; try / 连接到真实WEB服务器 IPEndPoint ipEndpoint = new IPEndPoint(address0, Port); IPsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPsocket.Connect(ipEndpoint); / 对WEB服务器端传送HTTP请求命令,将原始HTTP请求中HTTP PROXY部分包装去掉 string ReqData = ClientMsg; / 改写头中的URL, ReqData

16、= ReqData.Replace(http:/+RawUrl, Url); / 按照rn切分HTTP头 string ReqArray = ReqData.Split(new string1rn, StringSplitOptions.None); ReqData = ; / 改写Keep-Alive等字段 for (int index = 0; index ReqArray.Length; index+) /* if (ReqArrayindex.StartsWith(Accept-Encoding:) ReqArrayindex = Accept-Encoding: deflate; *

17、/ if (ReqArrayindex.StartsWith(Proxy-Connection:) ReqArrayindex = ReqArrayindex.Replace(Proxy-Connection:, Connection:); /ReqArrayindex = Connection: close; /* else if (ReqArrayindex.StartsWith(Keep-Alive:) ReqArrayindex = ; */ / 修改后的字段组合成请求 if( ReqArrayindex != ) ReqData = ReqData + ReqArrayindex +

18、 rn; ReqData = ReqData.Trim(); byte SendBuff = ASCII.GetBytes(ReqData); IPsocket.Send(SendBuff); catch( Exception e ) Console.WriteLine( 发送请求到服务器异常: + e.Message ); / 使用Poll来判断完成,某些站点会出问题 while (true) Byte RecvBuff = new byte1024 * 20; try if( !IPsocket.Poll( 15 * 1000 * 1000, SelectMode.SelectRead )

19、 ) Console.WriteLine(HTTP超时,关闭连接); break; catch (Exception e) Console.WriteLine(Poll: + e.Message); break; int Length = 0; try Length = IPsocket.Receive(RecvBuff); if (0 = Length) Console.WriteLine(服务端关闭); break; Console.WriteLine(从服务端收到字节, Length); catch (Exception e) Console.WriteLine(Recv: + e.Me

20、ssage); break; try Length = ClientSocket.Send(RecvBuff, Length, 0); Console.WriteLine(发送字节到客户端, Length); catch (Exception e) Console.WriteLine(Send: + e.Message); /* / 根据接收字节数来判断完成,某些站点会出问题 try while (true) Byte RecvBuff = new byte1024 * 10; int Length = IPsocket.Receive(RecvBuff); if (Length = 0) C

21、onsole.WriteLine(从服务端接收数据完成); break; Console.WriteLine(从服务端收到字节, Length); Length = ClientSocket.Send(RecvBuff, Length, 0); Console.WriteLine(发送字节到客户端, Length); catch (Exception e) Console.WriteLine(e.Message); */ try ClientSocket.Shutdown(SocketShutdown.Both); ClientSocket.Close(); IPsocket.Shutdown

22、(SocketShutdown.Both); IPsocket.Close(); catch (Exception e) /Console.WriteLine(e.Message); / / 在客户端和服务器之间中转数据 / / 客户端socket / 服务端socket private void ForwardTcpData(Socket client, Socket server) ArrayList ReadList = new ArrayList(2); while (true) ReadList.Clear(); ReadList.Add(client); ReadList.Add(

23、server); try Socket.Select(ReadList, null, null, 1 * 1000 * 1000); catch (SocketException e) Console.WriteLine(Select error: + e.Message); break; / 超时 if (ReadList.Count = 0) /Console.WriteLine(Time out); continue; / 客户端可读 if (ReadList.Contains(client) byte Recv = new byte1024 * 10; int Length = 0;

24、try Length = client.Receive(Recv, Recv.Length, 0); if (Length = 0) Console.WriteLine(Client is disconnect.); break; Console.WriteLine( Recv bytes from client, Length); catch (Exception e) Console.WriteLine(Read from client error: + e.Message); break; try Length = server.Send(Recv, Length, 0); Console.WriteLine( Write bytes to ser

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1