简单的代理服务器代码(C#)

发布时间:2009年06月04日      浏览次数:993 次
前天晚上账号用完了。于是,昨天想着可不可以在网页上写一个代理程序呢?说干就干,昨天早晨起来立即找资料,开始做起来。刚开始写了一个很简单的网页。没有涉及到代理。仅仅是让用户输入一个网址,然后在网页里面获取到该网页的内容,再呈现给用户。可是,这样做有很多不足。首先,图片无法显示。如果网页内容是通过javascript写入的,那就连内容也很难显示。其次,就是不能回传数据。比如我想在google里面搜索,用这种方法就难以实现了。
那么,怎么办呢?于是,我想着可不可以在网页中写一个正儿八经的代理程序?打开一个端口,然后侦听这个端口。当有用户连接这个端口的时候,就读取用户发过来的请求,然后把他的请求发给他想要请求的真正的目的的。这样不就是一个完整的代理了吗?于是,就试着按照网上搜的一段小代码开始写起来。
在本机调试,发现没有什么问题。确实可以实现。可惜,到了网上以后就不行了。我想问题应该出在防火墙上面。当这个网页联网的时候被防火墙给挡住了。
主要代码
//Proxy.cs
using System;
using System.Threading;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Timers;
/// <summary>
/// Proxy的摘要说明
/// </summary>
public class Proxy
{
Socket M_clientSocket;
/// <summary>
/// 存储来自客户端请求数据包
/// </summary>
//设定编码
Encoding ASCII = Encoding.ASCII;
//定义一个空间,存储Web服务器返回的数据
public Proxy(Socket socket)
{
//
// TODO: 在此处添加构造函数逻辑
//
this.M_clientSocket = socket;
}
public void Run()
{
Thread thread = new Thread(new ThreadStart(work));
thread.Start();
//work();
}
private void work()
{
Socket clientSocket = M_clientSocket;
//存放来自客户端的HTTP请求字符串
string clientmessage = " ";
string URL = " ";
//存放解析出地址请求信息
Byte[] ByteArray = new byte[4096];
int bytes = ReadMessage(ref ByteArray, ref clientSocket, ref clientmessage);
if (bytes == 0)
{
return;
}
else
{
Console.WriteLine("客户端请求的数据总长度:" + bytes.ToString());
}
// 找到请求连接的网站网址
int start = clientmessage.IndexOf("http://") + "http://".Length;
int end = clientmessage.IndexOf('/', start);
URL = clientmessage.Substring(start, end - start);
try
{
// 解析出要访问的服务器地址
IPHostEntry IPHost = Dns.GetHostEntry(URL);
Console.WriteLine("请求连接的网站网址: " + IPHost.HostName);
string[] aliases = IPHost.Aliases;
IPAddress[] address = IPHost.AddressList;
// Console.WriteLine("Web服务器IP地址:" + address[0]);
// 创建连接Web服务器端的Socket对象
IPEndPoint ipEndpoint = new IPEndPoint(address[0], 80);
Socket IPsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Socket连Web接服务器
IPsocket.Connect(ipEndpoint);
if (!IPsocket.Connected)
{
Console.WriteLine("Socket 连接失败!");
Thread.CurrentThread.Abort();
}
if (bytes < ByteArray.Length)
{
IPsocket.Send(ByteArray, bytes, 0);
}
else
{
byte[] getByte = ASCII.GetBytes(clientmessage);
IPsocket.Send(getByte, getByte.Length, 0);
}
// 从真正的服务器端获取数据然后发送给客户端
int ic = 0, iRecv = 0;
Byte[] RecvBytes = new Byte[512000];
//while (IPsocket.Available > 0)
//{
// iRecv = IPsocket.Receive(RecvBytes, RecvBytes.Length, 0);
// SendMessage(ref RecvBytes, clientSocket, iRecv);
// ic += iRecv;
//}
//int iCount = 0;
//while (!IPsocket.Poll(-1, SelectMode.SelectRead))
//{
// if (iCount++ > 1000)
// {
// Console.WriteLine("接收数据超时,线程结束!");
// Thread.CurrentThread.Abort();
// }
// Thread.Sleep(100);
//}
do
{
// Console.WriteLine(Thread.CurrentThread.ManagedThreadId.ToString()+":"+IPsocket.Available.ToString());

iRecv = IPsocket.Receive(RecvBytes, RecvBytes.Length, 0);
clientSocket.Send(RecvBytes, iRecv, SocketFlags.None);
ic += iRecv;
} while (iRecv > 0);
float fSize = ic;
if ((fSize /= 1024) < 1)
Console.WriteLine("服务器获取到的数据总长度:" + ic.ToString() + " Byte");
else if ((fSize /= 1024) < 1)
Console.WriteLine("服务器获取到的数据总长度:" + fSize * 1024 + " KB");
else
Console.WriteLine("服务器获取到的数据总长度:" + fSize + " MB");
IPsocket.Shutdown(SocketShutdown.Both);
IPsocket.Close();
}
catch (Exception exc2)
{
string strLog = exc2.ToString();
log(ref strLog);
Thread.CurrentThread.Abort();
}
}
private static void log(ref string strLog)
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + ":\t" + strLog);
}
// 接收客户端的HTTP请求数据
private int ReadMessage(ref Byte[] ByteArray, ref Socket s, ref String clientmessage)
{
int bytes = 0, iRecv = 0;
try
{
while (s.Available > 0)
{
iRecv = s.Receive(ByteArray, ByteArray.Length, SocketFlags.None);
clientmessage += Encoding.ASCII.GetString(ByteArray);
bytes += iRecv;
}
return bytes;
}
catch(SocketException e)
{
string strLog = "接受数据时出错\n" + clientmessage + "\ns" + s.Available;
//bytes=" + bytes.ToString() + "\tiRecv=" + iRecv.ToString());
log(ref strLog);
strLog = e.ToString();
log(ref strLog);
}
return bytes;
}
// 传送从Web服务器反馈的数据到客户端
private void SendMessage(ref Byte[] RecvBytes, ref Socket s, int iCount)
{
s.Send(RecvBytes, iCount, SocketFlags.None);
}
}
//使用页面WebProxy.cs
using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace WebProxy
{
class Program
{
static void Main(string[] args)
{
IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHost.AddressList[0];
const int port = 8000;
TcpListener tcplistener = new TcpListener(ipAddress, port);

try
{
tcplistener.Start();
Console.WriteLine("开始侦听:" + tcplistener.LocalEndpoint);
while (true)
{
Socket socket = tcplistener.AcceptSocket();
Proxy proxy = new Proxy(socket);
Thread thread = new Thread(new ThreadStart(proxy.Run));
thread.Start();
}
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
Console.ReadKey(true);
tcplistener.Stop();
}
}
}
}
免责声明:本站相关技术文章信息部分来自网络,目的主要是传播更多信息,如果您认为本站的某些信息侵犯了您的版权,请与我们联系,我们会即时妥善的处理,谢谢合作!