我正在编写代理服务器,我希望它具有高性能和可扩展性,因此我决定使用低级别的 api,例如System.Net.Sockets
.
到目前为止,我刚刚实现了一个简单的 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 一样的服务器,但它不是那样工作的。