我正在使用代理服务器并希望它具有高性能和scalabe,因为我决定使用像System.Net.Sockets
这样的低级api。
截至目前,我刚刚实现了一个简单的http代理服务器,它接收来自Web浏览器的请求,并简单地将请求转发给服务器,然后再将响应转发给客户端。事实证明,它消耗了 100%我的笔记本电脑的 CPU使用率。
我使用下面的代码,这很简单,可以改进,所以我的第一个问题是如何优化它以便不占用CPU的使用量?这是代码:
public void StartHandling()
{
while (!ThreadPool.QueueUserWorkItem(
new WaitCallback(Handler))) ;
}
private void Handler(object obj)
{
bool recvRequest = true;
string EOL = "\r\n";
string requestPayload = "";
string requestTempLine = "";
List<string> requestLines = new List<string>();
byte[] requestBuffer = new byte[1];
byte[] responseBuffer = new byte[1024];
requestLines.Clear();
try
{
//State 0: Handle Request from Client
while (recvRequest)
{
clientSocket.Receive(requestBuffer);
string fromByte = ASCIIEncoding.ASCII.GetString(requestBuffer);
requestPayload += fromByte;
requestTempLine += fromByte;
if (requestTempLine.EndsWith(EOL))
{
requestLines.Add(requestTempLine.Trim());
requestTempLine = "";
}
if (requestPayload.EndsWith(EOL + EOL))
{
recvRequest = false;
}
}
Console.WriteLine("Raw Request Received...");
Console.WriteLine(requestPayload);
//State 1: Rebuilding Request Information and Create Connection to Destination Server
string[] pars = requestLines[0].Split(' ');
string url;
string remoteHost;
string requestFile;
int port;
if (pars[0] == "GET")
{
url = pars[1].Replace("http://", "");
if (url.IndexOf(':') > 0)
throw new InvalidOperationException("Bad request!");
port = 80; // http port
}
else if (pars[0] == "CONNECT")
{
url = pars[1].Replace("https://", "").Replace(":443", "");
if (url.IndexOf(':') > 0)
throw new InvalidOperationException("Bad request!");
port = 443; // https port
}
else
throw new InvalidOperationException("Bad request!");
remoteHost = url.Split('/')[0];
requestFile = requestLines[0].Replace("https://", "").Replace("http://", "").Replace(remoteHost, "");
requestLines[0] = requestFile;
requestPayload = "";
foreach (string line in requestLines)
{
requestPayload += line;
requestPayload += EOL;
}
using (Socket destServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{
destServerSocket.Connect(remoteHost, port);
//State 2: Sending New Request Information to Destination Server and Relay Response to Client
destServerSocket.Send(ASCIIEncoding.ASCII.GetBytes(requestPayload));
//Console.WriteLine("Begin Receiving Response...");
while (destServerSocket.Receive(responseBuffer) != 0)
{
//Console.Write(ASCIIEncoding.ASCII.GetString(responseBuffer));
this.clientSocket.Send(responseBuffer);
}
//int totalReceived = destServerSocket.Receive(responseBuffer);
//while (totalReceived != 0)
//{
// clientSocket.Send(responseBuffer, totalReceived, SocketFlags.None);
// totalReceived = destServerSocket.Receive(responseBuffer);
//}
destServerSocket.Disconnect(false);
clientSocket.Disconnect(false);
}
}
catch (Exception e)
{
Console.WriteLine("Error Occured: " + e.Message);
//Console.WriteLine(e.StackTrace);
}
finally
{
clientSocket.Dispose();
Thread.CurrentThread.Abort();
}
}
我的第二个问题是如何处理 HTTPS 请求的?我实际上将HTTPS请求转发到服务器,就像HTTP一样,但它不能那样工作。