0

私はプロキシサーバーを作成していますが、それを高性能でスケーラブルにしたいので、 のような低レベルの API を使用することにしましたSystem.Net.Sockets

今のところ、Web ブラウザーから要求を受信し、要求をサーバーに転送し、応答をクライアントに再度転送する単純な HTTP プロキシ サーバーを実装しました。私のラップトップのCPU 使用率の100%を消費していることがわかりました。

私は以下のコードを使用していますが、これはシンプルで改善できるので、最初の質問は、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();
        }
    }

2 番目の質問は、 HTTPSリクエストをどのように処理できますか? 実際にはHTTPSリクエストをHTTPのようにサーバーに転送しますが、そのようには機能しません。

4

0 に答える 0