读书人

[分享与散分]Http 署理工具 实战 支持

发布时间: 2013-04-20 19:43:01 作者: rapoo

[分享与散分]Http 代理工具 实战 支持网页与QQ代理
作者:路过秋天
原文:http://www.cnblogs.com/cyq1162/archive/2010/09/21/1832329.html



有些公司不让员工上Q或封掉某些网站,这时候,干着急没办法,只能鄱墙。
如果上网搜代理IP,很少能用,用HTTP-Tunnel Client代理软件,免费的也是经常性的掉线。

正好手头上有N台服务器,如果直接在上面装个CCProxy,也显的太明显了。
于是自己写个代理软件放上去,一来包装一下好伪装,二来又有代理功能,看着挺好。



原理解说:

1:创建一个Socket进行本地端口监听-》一个死循环while语句

2:收到消息时,产生一个线程处理->多线程处理并发请求

3:产生一个新的Socket负责转发和接收

4:原来的Socket负责把新接收的消息发送回客户端



代码细说

说明:本次示例在控制台程序里运行。


一:Program.cs



1:简单函数原型


using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Net.Sockets;
using System.Threading;
namespace TcpProxy
{
/// <summary>
/// by 路过秋天
/// http://www.cnblogs.com/cyq1162
/// </summary>
class Program
{

static void Main(string[] args)
{
Listen(808);//起始监听808和CCProxy一样。
}
static void Write(string msg)//简化消息输出
{
Console.WriteLine(msg);
}

static void Listen(int port)//开始监听
{

}
static void ReListen(TcpListener listener)//监听失败,需要重新换端口监听
{

}
}
}



2:开始监听


static void Listen(int port)//开始监听
{
Write("准备监听端口:" + port);
System.Net.IPAddress ipp = System.Net.IPAddress.Parse("0.0.0.0");//监听本地任意IP
TcpListener tcplistener = new TcpListener(ipp, port);
//端口复用,xp下可以复用[可抢占IIS80端口],win2003下无效。
tcplistener.Server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
try
{
tcplistener.Start();
}
catch (Exception err)
{


Write(err.Message);
Write("该端口已被占用,请更换端口号!!!");
ReListen(tcplistener);//监听失败,切换端口监听
}
//下面还有代码,暂时省略

}


3:监听失败,切换端口监听


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);
}
}


4:开始监听,进入死循环


static void Listen(int port)//开始监听
{
//上面代码省略......

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();//启动线程
}
}


作者:路过秋天

博客:http://cyq1162.cnblogs.com/





二:Proxy.cs



Proxy简单函数原型:


using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace TcpProxy
{
/// <summary>
/// by 路过秋天
/// http://www.cnblogs.com/cyq1162
/// </summary>
public class Proxy
{
Socket clientSocket;//接收和返回
byte[] read = null;//存储来自客户端请求数据包
byte[] sendBytes = null;//存储中转请求发送的数据
byte[] recvBytes = null;//存储中转请求返回的数据
bool isConnect = false;
byte[] qqSendBytes=new byte[4096];//QQ发送缓冲
byte[] qqRecvBytes = new byte[4096];//QQ接收缓冲
int sendLength = 0, recvLength = 0;//实际发送和接收长度
public Proxy(Socket socket)//初始化
{
clientSocket = socket;
recvBytes = new Byte[1024 * 1024];
clientSocket.ReceiveBufferSize = recvBytes.Length;
clientSocket.SendBufferSize = recvBytes.Length;
}

public void Run(){}//主运行代码
//从请求头里解析出url和端口号
private string GetUrl(string clientmessage, ref int port){}
//接收客户端的HTTP请求数据
private int ReadMessage(byte[] readByte, ref Socket s, ref IPAddress ipAddress, ref string host, ref int port){}
//关闭socket
private void CloseSocket(Socket socket){}
private void CloseSocket(Socket socket, bool shutdown){}
//QQ代理测试返回
private byte[] QQokProxyData(){}
//firfox默认会发送一些请求,很烦,所以加过滤
private bool Filter(string url){ }
private void Write(string msg)
{
System.Console.WriteLine(msg);
}

}
}



Run主函数



A:分解请求头,获取要请求的IP,端口


#region 获取客户端请求数据


Write("-----------------------------请求开始---------------------------");

read = new byte[clientSocket.Available];
IPAddress ipAddress = IPAddress.Any;
string host = "";//主机
int port = 80;//端口

int bytes = ReadMessage(read, ref clientSocket, ref ipAddress, ref host, ref port);
if (bytes == 0)
{
Write("读取不到数据!");
CloseSocket(clientSocket);
return;
}
#endregion


Run函数分解:ReadMessage函数

ReadMessage函数
//接收客户端的HTTP请求数据
private int ReadMessage(byte[] readByte, ref Socket s, ref IPAddress ipAddress, ref string host, ref int port)
{
try
{

int bytes = s.Receive(readByte, readByte.Length, 0);
Write("收到原始请求数据:" + readByte.Length);
string header = Encoding.ASCII.GetString(readByte);


host = GetUrl(header, ref port);
if (Filter(host))
{
Write("系统过滤:" + host);
return 0;
}
Write(header);
ipAddress = Dns.GetHostAddresses(host)[0];
if (!isConnect)
{
header = header.Replace("http://" + host, "");


}
sendBytes = Encoding.ASCII.GetBytes(header);
System.Threading.Thread.Sleep(50);
Write("转发请求数据:" + sendBytes.Length);
Write(Encoding.ASCII.GetString(sendBytes));
return bytes;
}
catch
{
System.Threading.Thread.Sleep(300);
return 0;
}
}


ReadMessage函数分解:GetUrl

GetUrl函数
//从请求头里解析出url和端口号
private string GetUrl(string clientmessage, ref int port)
{
if (clientmessage.IndexOf("CONNECT") != -1)
{
isConnect = true;
}
int index1 = clientmessage.IndexOf(' ');
int index2 = clientmessage.IndexOf(' ', index1 + 1);
if ((index1 == -1) || (index2 == -1))
{
return "";
}
string part1 = clientmessage.Substring(index1 + 1, index2 - index1).Trim();
string url = string.Empty;
if (!part1.Contains("http://"))
{
if (part1.Substring(0, 1) == "/")
{
part1 = "127.0.0.1" + part1;
}
part1 = "http://" + part1;


}
Uri uri = null;
try
{
uri = new Uri(part1);
}
catch
{
return "";
}
url = uri.Host;
port = uri.Port;
return url;
}


ReadMessage函数分解:Filter

Filter函数
private bool Filter(string url)
{
switch (url.ToLower())
{
case "fffocus.cn":
return true;
}
return false;
}


Run函数分解:CloseSocket函数

CloseSocket函数
private void CloseSocket(Socket socket)
{
CloseSocket(socket, true);
}
private void CloseSocket(Socket socket, bool shutdown)
{
if (socket != null)
{
if (shutdown)
{
socket.Shutdown(SocketShutdown.Both);
}
socket.Close();
}
}


B:创建中转Socket及建立连接


#region 创建中转Socket及建立连接
IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, port);
Socket IPsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);


try
{
IPsocket.Connect(ipEndpoint); Write("-----Socket 建立连接! IP地址:" + ipAddress + "网址:http://" + host);
}
catch (Exception err)
{
Write("连接失败 :" + err.Message);
Write("退出请求!!!");
CloseSocket(IPsocket, false);
return;
}
#endregion

//说明:帖子太长,贴不完:完整内容请看原文链接


结言:

本QQ代理软件在服务器上运行长达三个多月,使用过程未发现异常退出情况。当然前提就我一个人在用了~哈哈~




看本篇的时候也请支持一下我的开源框架:CYQ.Data 轻量数据层之路 框架开源系列 索引


[解决办法]
监听自己老是弄不太明白,
[解决办法]
[分享与散分]Http 署理工具 实战 支持网页与QQ代理不懂socket,学习一下
[解决办法]
看看
[解决办法]
收藏。
[解决办法]
[分享与散分]Http 署理工具 实战 支持网页与QQ代理按你博客里的代码重敲了一遍,好多地方看不懂
System.Net.IPAddress ipp = System.Net.IPAddress.Parse("0.0.0.0");//这是什么
case "fffocus.cn"://这是什么
string data = "http://1.0 200 Connection established";//这是什么
part1 = "127.0.0.1" + part1;//这是什么
[解决办法]


[解决办法]
[分享与散分]Http 署理工具 实战 支持网页与QQ代理围观下。(*^__^*) 嘻嘻……
[解决办法]
兄弟来个源码下载呀。。。 要不发一份到邮箱 312852086@qq.com
[解决办法]
[分享与散分]Http 署理工具 实战 支持网页与QQ代理
------解决方案--------------------


好东西啊~~顶起
[解决办法]
谢谢 好东西!

读书人网 >C#

热点推荐