【问题标题】:Create a simple proxy using Sockets使用 Sockets 创建一个简单的代理
【发布时间】:2014-01-03 03:51:23
【问题描述】:

有人可以帮我弄清楚我在代码中做错了什么。

我正在尝试使用套接字创建一个简单的 HTTP 代理。无论如何我都不想更改请求或响应,我只想能够中继请求/响应并记录来自浏览器的 url 请求。

这段代码不能正常工作,我意识到有几个关于 SO 的问题与使用 c# 的代理和套接字有关,但我仍然无法弄清楚我做错了什么。

问题似乎出在我的 socket.receive 上,它很慢并且需要很长时间才能完成。浏览器最多等待 10/20 秒...

   int bytes = 0;
                do
                {
                    bytes = destServerSocket.Receive(responseBuffer);
                    client.Send(responseBuffer);
                }
                while (bytes > 0);

有时我在发送标头时收到(SocketException:现有连接被远程主机强制关闭)。

收到响应时,有时我会收到(SocketException:已建立的连接被主机中的软件中止)

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

namespace Proxy
{
    class Program
    {

        static void Main(string[] args)
        {
            TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 8888);
            server.Start();

            while (true)
            {
                Socket client = server.AcceptSocket();
                Thread t = new Thread(new ParameterizedThreadStart(Program.Handle));
                t.Start(client);
                //Thread.Sleep(30);
            }
        }

        static void Handle(object clientSocket)
        {
            Socket client = (Socket)clientSocket;
            bool recveiveRequest = true;
            string EOL = "\r\n";

            string headers = "";
            string requestTempLine = "";
            List<string> requestLines = new List<string>();
            byte[] requestBuffer = new byte[1];
            byte[] responseBuffer = new byte[1024];

            Socket destServerSocket = null;

            requestLines.Clear();

            try
            {
                while (recveiveRequest)
                {
                    client.Receive(requestBuffer);
                    string fromByte = ASCIIEncoding.ASCII.GetString(requestBuffer);
                    headers += fromByte;
                    requestTempLine += fromByte;

                    if (requestTempLine.EndsWith(EOL))
                    {
                        requestLines.Add(requestTempLine.Trim());
                        requestTempLine = "";
                    }

                    if (headers.EndsWith(EOL + EOL))
                    {
                        recveiveRequest = false;
                    }
                }
                Console.WriteLine("Raw Request Received...");
                Console.WriteLine(headers);

                // TODO: record headers

                string remoteHost = requestLines[0].Split(' ')[1].Replace("http://", "").Split('/')[0];
                string requestFile = requestLines[0].Replace("http://", "").Replace(remoteHost, "");
                requestLines[0] = requestFile;

                headers = "";
                foreach (string line in requestLines)
                {
                    headers += line;
                    headers += EOL;
                }

                destServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                destServerSocket.Connect(remoteHost, 80);
                destServerSocket.Send(ASCIIEncoding.ASCII.GetBytes(headers));

                int bytes = 0;
                do
                {
                    bytes = destServerSocket.Receive(responseBuffer);
                    client.Send(responseBuffer);
                }
                while (bytes > 0);

            }
            catch (Exception e)
            {
                Console.WriteLine("Error Occured: " + e.Message);
            }
            finally
            {
                destServerSocket.Close();
                client.Close();
            }
        }

    }
}

谢谢,感谢任何帮助...

【问题讨论】:

    标签: c# sockets proxy


    【解决方案1】:

    尝试分析您的代码以查看性能问题。尝试增加 responseBuffer 的大小,改进标头解析代码(一个接一个地接收字节,将它们转换为字符串并使用 += 而不是 StringBuilder 等添加到字符串),您还可以缓存到远程的连接服务器而不是在每个请求上重新创建它们等等。但是在进行任何更改之前,最好先分析您的代码以查看真正的问题。

    另外,我建议阅读一些优秀代码示例,以便代理学习一些技巧。您当前的代码看起来非常幼稚且效率低下。

    【讨论】:

      【解决方案2】:

      一旦您接受了您的套接字,您应该使用异步模型并连接一个事件侦听器以接收来自代理双方(客户端和客户端)的传入数据。这将防止阻塞。然后你就可以摆脱所有的while循环了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-18
        • 1970-01-01
        • 2013-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-07
        相关资源
        最近更新 更多