用C#写的一个最简单最简单的代理服务器,求指教

ryantao2010 2012-08-16 07:03:20
小弟是初学者,想写一个用localhost,端口8081的最简单最简单代理服务器,代码如下。这个代理纯粹从客户端接收请求然后原封不动发送到服务器,再从服务器接收信息原封不动返回客户端。思路是用两个socket,其中clientSock是连接客户端另一个是连接服务器的,一个List<byte>储存所有接收到的byte然后再传送回clientSock。问题是这个代理反映非常慢,浏览网页也只是偶然可以成功一下。我想知道问题所在,谢谢了!

using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Net;
using System.Threading;

namespace LocalhostProxy
{
class Program
{
static void Main(string[] args)
{
const int DEFPORTNUM = 8081;
int port2use = DEFPORTNUM;
const int BACKLOG = 10; // maximum length of pending connections queue

Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

// Establish the local endpoint for the socket
IPAddress ipAddress = IPAddress.Loopback;
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port2use);

listener.Bind(localEndPoint);
listener.Listen(BACKLOG);
System.Console.WriteLine("Listening ... " + localEndPoint.ToString());

while (true)
{
Socket sock = listener.Accept();
//if(sock.Connected)
// System.Console.WriteLine("Connection established");
RequestHandler rh = new RequestHandler(sock);
Thread rhThread = new Thread(new ThreadStart(rh.DoRequest));
rhThread.Start();
}
}
}
class RequestHandler
{
public RequestHandler(Socket sock)
{
System.Text.Encoding utf8 = System.Text.Encoding.UTF8;
List<byte> requestBytesList = new List<byte>();

// Get the HTTP headers first
Header = "";
while (true)
{
RequestBytes = new byte[1];
int bytesRec = sock.Receive(RequestBytes);
requestBytesList.Add(RequestBytes[0]);
Header += System.Text.Encoding.ASCII.GetString(RequestBytes, 0, bytesRec);
if (Header.IndexOf("\r\n\r\n") > -1 || Header.IndexOf("\n\n") > -1)
{
break;
}
}
System.Console.WriteLine("*** Headers ***\n " + Header);

// Break up the headers
string[] headers = Header.Split(new char[] { '\n' });
string requestLine = headers[0];
string[] requestLineElements = requestLine.Split(new char[] { ' ' });

RequestMethod = requestLineElements[0];
Resource = requestLineElements[1];
HttpVersion = requestLineElements[2];

Uri uri = new Uri(Resource);

Host = uri.Host;
Port = uri.Port;

for (int i = 1; i < headers.Length; i++)
{
RequestHeaders += headers[i] + "\r\n";
}

clientSock = sock;

RequestBytes = requestBytesList.ToArray();
/*
Console.WriteLine("Request method:" + RequestMethod);
Console.WriteLine("Resource: " + Resource);
Console.WriteLine("HttpVersion:" + HttpVersion);
Console.WriteLine("Host: " + Host);
Console.WriteLine("Request Headers: \n" + RequestHeaders);
*/
}
public void DoRequest()
{
System.Text.Encoding utf8 = System.Text.Encoding.UTF8;
const int BUFSZ = 1024;

try
{
// IPAddress and IPEndPoint represent the endpoint that will
// receive the request.
// Get the first IPAddress in the list using DNS.

IPAddress hostadd = Dns.GetHostEntry(Host).AddressList[0];
if (Host == "localhost")
{
hostadd = IPAddress.Loopback;
}
IPEndPoint remoteEndPoint = new IPEndPoint(hostadd, Port);

//Console.WriteLine(remoteEndPoint.ToString());

//Creates the Socket for sending data over TCP.
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.ReceiveTimeout = 20 * 1000; // Set time out (milliseconds)

// Connects to the host using IPEndPoint.
s.Connect(remoteEndPoint);
s.Send(RequestBytes, RequestBytes.Length, SocketFlags.None);

// Get the HTTP headers first
List<byte> ResponseBytesList = new List<byte>();
string header = "";
while (true)
{

byte[] bytes = new byte[1];
int bytesRec = s.Receive(bytes);
//if (bytesRec != 0)
// Console.WriteLine("Receive some bytes");
header += System.Text.Encoding.UTF8.GetString(bytes, 0, bytesRec);
for (int i = 0; i < bytesRec; i++)
{
ResponseBytesList.Add(bytes[i]);
}

if (header.IndexOf("\r\n\r\n") > -1 || header.IndexOf("\n\n") > -1)
{
//Console.WriteLine("Blank line found");
break;
}
}
Console.WriteLine(header);

// Break up the headers
string[] headers = header.Split(new char[] { '\n' });

// Get the HTTP payload next
string data = header;
int contentLength = GetContentLength(headers);

//Console.WriteLine(utf8.GetString(ResponseBytes, 0, ResponseBytes.Length));

if (RequestMethod == "HEAD")
{
contentLength = 0; // no contents for "HEAD"
}
try
{
if (contentLength > 0)
{
int bytesRecd = 0;
while (bytesRecd < contentLength)
{
byte[] bytes = new byte[BUFSZ];
int bytesNowGot = s.Receive(bytes);
for(int i = 0 ; i < bytesNowGot; i++)
{
ResponseBytesList.Add(bytes[i]);
}
bytesRecd += bytesNowGot;
data += System.Text.Encoding.UTF8.GetString(bytes, 0, bytesNowGot);
}
}
else
{
int bytesNowGot = 0;
do
{
byte[] bytes = new byte[BUFSZ];
bytesNowGot = s.Receive(bytes);
for (int i = 0; i < bytesNowGot; i++)
{
ResponseBytesList.Add(bytes[i]);
}
data += System.Text.Encoding.UTF8.GetString(bytes, 0, bytesNowGot);
} while (bytesNowGot > 0);
}
ResponseBytes = ResponseBytesList.ToArray();
clientSock.Send(ResponseBytes);
}
catch (System.Exception)
{

}
//Console.WriteLine("data \n" + data);
s.Shutdown(SocketShutdown.Both);
s.Close();
}catch (Exception ex)
{
//Console.WriteLine(ex.ToString());

}
}// DoRequest

private static int GetContentLength(string[] headers)
{
int rval = 0;
for (int i = 1; i < headers.Length; ++i) // 0 = requestLine
{
string[] hElem = headers[i].Split(new char[] { ':' });
if (hElem.Length >= 2)
{
if (hElem[0].Trim().ToLowerInvariant().Equals("content-length"))
{
rval = Int32.Parse(hElem[1].Trim());
}
}
}
return rval;
} // GetContentLength
public string Host
{
get;
private set;
} // Host
public int Port
{
get;
private set;
} // Port
public string HttpVersion
{
get;
set;
} // HttpVersion
public string Resource
{
get;
private set;
} // Resource
public string RequestMethod
{
get;
private set;
} // RequestMethod
public string RequestHeaders
{
get;
private set;
} // RequestHeaders
public string Response
{
get;
set;
} // Response
public string Header
{
get;
private set;
}
public Socket clientSock
{
get;
private set;
}
public byte[] RequestBytes
{
get;
private set;
}
public byte[] ResponseBytes
{
get;
private set;
}
} // class RequestHandler
}// namespace LocalhostProxy
...全文
518 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
hiteali 2012-08-21
  • 打赏
  • 举报
回复
byte[] bytes = new byte[BUFSZ];
int bytesNowGot = 0;
while ((bytesNowGot = serverSock.Receive(bytes, 0, bytes.Length, SocketFlags.None)) > 0)
{
sock.Send(bytes, 0, bytesNowGot, SocketFlags.None);
bytes = new byte[BUFSZ];
}
宝_爸 2012-08-16
  • 打赏
  • 举报
回复
看看 open source的代码

his Mini Proxy Server writen in C#. It supports HTTP and HTTPS protocols.
http://miniproxyserver.codeplex.com/
newtee 2012-08-16
  • 打赏
  • 举报
回复
慢是必须的 这就是专业和不专业的区别

110,561

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧