粗糙的C#版HTTP代理Word文档下载推荐.docx
- 文档编号:16422682
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:22
- 大小:20.06KB
粗糙的C#版HTTP代理Word文档下载推荐.docx
《粗糙的C#版HTTP代理Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《粗糙的C#版HTTP代理Word文档下载推荐.docx(22页珍藏版)》请在冰豆网上搜索。
publicclassHttpProxy
intProxyPort;
///<
summary>
///代理服务器入口类构造函数
/summary>
paramname="
Port"
>
HttpProxy监听的端口<
/param>
publicHttpProxy(intPort)
ProxyPort=Port;
}
///启动Http代理服务器
publicvoidStart()
TcpListenertcplistener=null;
try
//开始监听端口
tcplistener=newTcpListener(Dns.GetHostAddresses(Dns.GetHostName())[0],ProxyPort);
tcplistener.Start();
Console.WriteLine("
侦听端口号:
"
+ProxyPort.ToString());
catch(Exceptione)
启动代理服务器失败:
+e.Message);
while(true)
//接受客户端连接
Socketsocket=tcplistener.AcceptSocket();
HttpSessionSession=newHttpSession(socket);
//启动新线程,处理连接
Threadthread=newThread(newThreadStart(Session.Start));
thread.Start();
catch(Exceptione)
接受客户端连接异常:
+e.Message);
publicclassHttpSession
//客户端socket
SocketClientSocket;
//设定编码
EncodingASCII=Encoding.ASCII;
///构造函数
socket"
客户端socket<
publicHttpSession(Socketsocket)
this.ClientSocket=socket;
publicvoidStart()
//客户端缓冲区,读取客户端命令
Byte[]ReadBuff=newbyte[1024*10];
intLength=ClientSocket.Receive(ReadBuff);
//没有读到数据
if(0==Length)
从客户端读取命令错误"
);
ClientSocket.Shutdown(SocketShutdown.Both);
ClientSocket.Close();
return;
//读取出现异常
读取客户端异常:
//来自客户端的HTTP请求字符串
stringClientMsg=ASCII.GetString(ReadBuff);
//根据rnrn截取请求行
stringLine=ClientMsg.Substring(0,ClientMsg.IndexOf("
rn"
));
string[]CmdArray=Line.Split('
'
//GET
:
80/index.phpHTTP/1
//CONNECT:
443HTTP/1
stringCmd=CmdArray[0];
stringRawUrl=CmdArray[1];
原始请求:
Line);
//CONNECT请求
if(Cmd=="
CONNECT"
)
DoConnect(RawUrl);
//GET,POST和其他
else
DoOther(RawUrl,ClientMsg);
///处理CONNECT命令,此处作用是支持QQ,MSN,以及多级代理串联等
RawUrl"
<
privatevoidDoConnect(stringRawUrl)
string[]Args=RawUrl.Split('
'
);
stringHost=Args[0];
intPort=int.Parse(Args[1]);
SocketServerSocket=null;
IPAddress[]IpList=Dns.GetHostEntry(Host).AddressList;
尝试连接:
"
IpList[0],Port);
ServerSocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
ServerSocket.Connect(IpList[0],Port);
连接真实服务器异常:
//连接真实服务器成功
if(ServerSocket.Connected)
ClientSocket.Send(ASCII.GetBytes("
HTTP/0200Connectionestablishedrnrn"
));
//开始转发数据
ForwardTcpData(ClientSocket,ServerSocket);
///处理GET,POST等命令。
使用了POLL,在代理服务器中强制去掉了Keep-Alive能力
ClientMsg"
publicvoidDoOther(stringRawUrl,stringClientMsg)
RawUrl=RawUrl.Substring(0+"
http:
//"
.Length);
intPort;
stringHost;
stringUrl;
//下面是分割处理请求,此处应该用正则匹配,不过我不擅长,因此手动切割,—_—!
intindex1=RawUrl.IndexOf('
//没有端口
if(index1==-1)
Port=80;
intindex2=RawUrl.IndexOf('
/'
//没有目录
if(index2==-1)
Host=RawUrl;
Url="
/"
;
Host=RawUrl.Substring(0,index2);
Url=RawUrl.Substring(index2);
Host=RawUrl.Substring(0,index1);
Port=IntParse(RawUrl.Substring(index1+1));
///出现在:
之前,则说明:
后面的不是端口
if(index2<
index1)
Port=IntParse(RawUrl.Substring(index1+1,index2-index1-1));
Hostis:
Portis:
Urlis:
Host,Port,Url);
IPAddress[]address=null;
IPHostEntryIPHost=Dns.GetHostEntry(Host);
address=IPHost.AddressList;
Web服务器IP地址:
+address[0]);
Console.WriteLine("
解析服务器地址异常:
SocketIPsocket=null;
//连接到真实WEB服务器
IPEndPointipEndpoint=newIPEndPoint(address[0],Port);
IPsocket=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPsocket.Connect(ipEndpoint);
//对WEB服务器端传送HTTP请求命令,将原始HTTP请求中HTTPPROXY部分包装去掉
stringReqData=ClientMsg;
//改写头中的URL,
ReqData=ReqData.Replace("
+RawUrl,Url);
//按照rn切分HTTP头
string[]ReqArray=ReqData.Split(newstring[1]{"
},StringSplitOptions.None);
ReqData="
//改写Keep-Alive等字段
for(intindex=0;
index<
ReqArray.Length;
index++)
/*
if(ReqArray[index].StartsWith("
Accept-Encoding:
))
ReqArray[index]="
deflate"
*/
Proxy-Connection:
ReqArray[index]=ReqArray[index].Replace("
"
Connection:
//ReqArray[index]="
close"
elseif(ReqArray[index].StartsWith("
Keep-Alive:
//修改后的字段组合成请求
if(ReqArray[index]!
="
)
ReqData=ReqData+ReqArray[index]+"
ReqData=ReqData.Trim();
byte[]SendBuff=ASCII.GetBytes(ReqData);
IPsocket.Send(SendBuff);
发送请求到服务器异常:
//使用Poll来判断完成,某些站点会出问题
Byte[]RecvBuff=newbyte[1024*20];
if(!
IPsocket.Poll(15*1000*1000,SelectMode.SelectRead))
HTTP超时,关闭连接"
break;
Poll:
intLength=0;
Length=IPsocket.Receive(RecvBuff);
服务端关闭"
从服务端收到字节"
Length);
Recv:
Length=ClientSocket.Send(RecvBuff,Length,0);
发送字节到客户端"
Send:
//根据接收字节数来判断完成,某些站点会出问题
Byte[]RecvBuff=newbyte[1024*10];
intLength=IPsocket.Receive(RecvBuff);
if(Length<
=0)
从服务端接收数据完成"
Console.WriteLine(e.Message);
IPsocket.Shutdown(SocketShutdown.Both);
IPsocket.Close();
//Console.WriteLine(e.Message);
///在客户端和服务器之间中转数据
client"
server"
服务端socket<
privatevoidForwardTcpData(Socketclient,Socketserver)
ArrayListReadList=newArrayList
(2);
ReadList.Clear();
ReadList.Add(client);
ReadList.Add(server);
Socket.Select(ReadList,null,null,1*1000*1000);
catch(SocketExceptione)
Selecterror:
//超时
if(ReadList.Count==0)
//Console.WriteLine("
Timeout"
continue;
//客户端可读
if(ReadList.Contains(client))
byte[]Recv=newbyte[1024*10];
Length=client.Receive(Recv,Recv.Length,0);
if(Length==0)
Clientisdisconnect."
Recvbytesfromclient"
Readfromclienterror:
Length=server.Send(Recv,Length,0);
Writebytestoser
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 粗糙 C# HTTP 代理