简单实现Http代理工具(转)

本来意图是想写个工具放到服务器里代理一下上秋秋的。

没想到N台(电信/联通/移动)的服务器都把端口全封了。

所以以下代码是在本地测试代理网页访问通过。

 

说下思路再上代码及下载:

其实一句话就是:产生两个Soket,一个负责接收请求和回发请求,另一个负责中转的去请求和接收。

重点一句话就是:每个请求产生一个线程处理,处理时关键是的延时处理(不然数据接收不全)。

 

现在上代码,Proxy自定义类:

 

Proxy
using  System;
using
 System.Collections.Generic;
using
 System.Text;
using
 System.Net;
using
 System.Net.Sockets;
using System.IO;
//by 路过秋天
namespace
 TCPProxy
{
    
public class
 Proxy
    {
        Socket clientSocket;
//接收和返回

        Byte[] read = null;//存储来自客户端请求数据包
        Byte[] recvBytes = null;//存储中转请求返回的数据

        
public  Proxy(Socket socket)
        {
            clientSocket 
=
 socket;
            recvBytes 
= new Byte[1024 * 1024
];
            clientSocket.ReceiveBufferSize 
=
 recvBytes.Length;
            clientSocket.SendBufferSize 
=
 recvBytes.Length;
            clientSocket.SendTimeout 
= 10000
;
            clientSocket.ReceiveTimeout 
= 10000
;
        }
        
public void
 Run()
        {
            
#region 获取客户端请求数据

            
string clientmessage = "" ;
            read 
= new byte
[clientSocket.Available];
            
int bytes = ReadMessage(read, ref clientSocket, ref
 clientmessage);
            
if (bytes == 0
)
            {
                Write(
"读取不到数据!"
);
                clientSocket.Shutdown(SocketShutdown.Both);
                clientSocket.Close();
                
return
;
            }
            
int port = 80
;
            
string url =
 GetUrl(clientmessage, port);
            
#endregion

            
            
try
            {
                
#region IP解析获取
                IPHostEntry IPHost
=  Dns.GetHostEntry(url);
                Write(
"-----------------------------请求开始---------------------------"
);
                Write(
"http://" +
 IPHost.HostName);
                
string[] aliases =
 IPHost.Aliases;
                IPAddress[] address 
= IPHost.AddressList;//解析出要访问的服务器地址

                Write("IP地址:" + address[0 ]);
                
#endregion

               

                
#region 创建中转Socket及建立连接
                IPEndPoint ipEndpoint 
= new IPEndPoint(address[0 ], port);
                Socket IPsocket 
= new
 Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                
//创建连接Web服务器端的Socket对象

                IPsocket.Connect(ipEndpoint);
                
//Socket连Web接服务器

                if  (IPsocket.Connected)
                {
                    Write(
"Socket 正确连接!"
);
                }
                
#endregion

                
#region 发送中转请求
                IPsocket.Send(read, 
0 );
                Write(
"发送字节:" +
 read.Length);
                
#endregion

                
#region 接收中转请求数据
                
int length = 0, count = 0 ;
                
do

                {
                    length 
= IPsocket.Receive(recvBytes, count, IPsocket.Available, 0 );
                    count 
= count +
 length;
                    Write(
"正在接收数据..." +
 length);
                    System.Threading.Thread.Sleep(
100);//关键点,请求太快数据接收不全

                }
                
while (IPsocket.Available > 0
);
                
#endregion

                
#region 关闭中转请求Socket
                IPsocket.Shutdown(SocketShutdown.Both);
                IPsocket.Close();
                
#endregion

                
#region 将中转请求收到的数据发回客户端
                clientSocket.Send(recvBytes, 
0, count, 0 );
                Write(
"正在返回数据..." +
 count);
                
#endregion

                
#region 结束请求,关闭客户端Socket
                clientSocket.Shutdown(SocketShutdown.Both);
                clientSocket.Close();
                recvBytes 
= null ;
                Write(
"完成,已关闭连接..."
);
                Write(
"-----------------------------请求结束---------------------------"
);
                
#endregion

            }
            
catch  (Exception err)
            {
                System.Console.WriteLine(err.Message 
+
 err.Source);
            }

        }
        
//从请求头里解析出url和端口号

        private string GetUrl(string clientmessage, int  port)
        {
            
int index1 = clientmessage.IndexOf(' '
);
            
int index2 = clientmessage.IndexOf(' ', index1 + 1
);
            
if ((index1 == -1|| (index2 == -1
))
            {
                
throw new
 IOException();
            }
            
string part1 = clientmessage.Substring(index1 + 1, index2 -
 index1).Trim();

            
string url = string
.Empty;
            
if (!part1.Contains("http://"
))
            {
                part1 
= "http://" +
 part1;
            }
            Uri uri 
= new
 Uri(part1);
            url 
=
 uri.Host;
            port 
=
 uri.Port;
            
return
 url;
        }
        
//接收客户端的HTTP请求数据

        private int ReadMessage(byte[] readByte, ref Socket s, ref string  clientmessage)
        {
            
int bytes = s.Receive(readByte, readByte.Length, 0
);
            clientmessage 
=
 Encoding.ASCII.GetString(readByte);
            
return
 bytes;
        }

        
private void Write(string
 msg)
        {
            
// return;

            System.Console.WriteLine(msg);
        }
    }
}

 

 

在控制台里调用:

 

代码
using  System;
using
 System.Collections.Generic;
using
 System.Text;
using
 System.Diagnostics;
using
 System.Net.Sockets;
using
 System.Threading;
namespace
 TCPProxy
{
    
class
 Program
    {
        
static void Main(string
[] args)
        {
                Listen(
8989
);
        }
        
static void Write(string
 msg)
        {
            Console.WriteLine(msg);
        }

        
static void Listen(int
 port)
        {
            Write(
"准备监听端口:" +
 port);
            TcpListener tcplistener 
= new
 TcpListener(port);
            
try

            {
                tcplistener.Start();
            }
            
catch
            {
                Write(
"该端口已被占用,请更换端口号!!!" );
                ReListen(tcplistener);
            }
            Write(
"确认:y/n (yes or no):"
);
            
string isOK =
 Console.ReadLine();
            
if (isOK == "y"
)
            {
                Write(
"成功监听端口:" +
 port);
                
//侦听端口号 

                Socket socket;
                
while (true
)
                {
                    socket 
=
 tcplistener.AcceptSocket();
                    
//并获取传送和接收数据的Scoket实例 

                    Proxy proxy = new  Proxy(socket);
                    
//Proxy类实例化 

                    Thread thread = new Thread(new  ThreadStart(proxy.Run));
                    
//创建线程 

                    thread.Start();
                    System.Threading.Thread.Sleep(
10
);
                    
//启动线程 

                }
            }
            
else

            {
                ReListen(tcplistener);
            }
        }
        
static void  ReListen(TcpListener listener)
        {
            
if (listener != null
)
            {
                listener.Stop();
                listener 
= null
;
            }
            Write(
"请输入监听端口号:"
);
            
string newPort =
 Console.ReadLine();
            
int
 port;
            
if (int.TryParse(newPort, out
 port))
            {
                Listen(port);
            }
            
else

            {
                ReListen(listener);
            }
        }
    }
}

 

 

本人测试:

在打开IE-》工具->Internet选项->链接->局域网设置->代理连接-》输入IP和端口号

访问网站,查看控制台输出消息,页面访问正常,测试通过。

 

本来想测试下QQ代理,无奈本地已被封,服务器也没端口可用。有空回家再测了。

 

提供代码下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值