C#中的简单代理服务器

 收藏

我编写了一个简单且极简的HTTP代理服务器,该服务器在命令行上运行。在Start()方法中,TcpListener阻塞,直到它获得客户端请求并创建一个新线程(ThreadHandleClient方法)来处理该客户端,获取其url并中继数据。

问题出在我要优化的继电器逻辑中。在第一个内部循环中,我接收所有Web服务器数据并将其发送给客户端,直到剩下零字节为止。在第二个内部循环中,我反之亦然:接收所有客户端数据并将其发送到Web服务器,直到剩余零字节为止。但是,代码在client.receive()的第二个内部循环的开始处被阻塞。这是我基本上正在做的:

任何帮助将不胜感激。提前致谢。

public void Start(IPAddress ip, int port)
    {
        try
        {
            TcpListener listener = new TcpListener(ip, port);
            listener.Start(100);
            while (!stopFlag)
            {
                Socket client = listener.AcceptSocket();
                IPEndPoint rep = (IPEndPoint)client.RemoteEndPoint;
                Thread th = new Thread(ThreadHandleClient);
                th.Start(client);
            }



        listener.Stop();
    }
    catch (Exception ex)
    {
        Debug.Print("START: " + ex.Message);
    }
}        

public void ThreadHandleClient(object o)
{
    try
    {
        Socket client = (Socket)o;
        NetworkStream ns = new NetworkStream(client);
        //RECEIVE CLIENT DATA
        byte[] buffer = new byte[2048];
        int rec = 0, sent = 0, transferred = 0, rport = 0;
        string data = "";
        do
        {
            rec = ns.Read(buffer, 0, buffer.Length);
            data += Encoding.ASCII.GetString(buffer, 0, rec);
        } while (rec == buffer.Length);

        //PARSE DESTINATION AND SEND REQUEST
        string line = data.Replace("\r\n", "\n").Split(new string[] { "\n" }, StringSplitOptions.None)[0];
        Uri uri = new Uri(line.Split(new string[] { " " }, StringSplitOptions.None)[1]);
        Debug.Print("CLIENT REQUEST RECEIVED: " + uri.OriginalString);
        if (uri.Scheme == "https")
        {
            rport = 443;
            Debug.Print("HTTPS - 443");
        }
        else
        {
            rport = 80;
            Debug.Print("HTTP - 443");
        }
        IPHostEntry rh = Dns.GetHostEntry(uri.Host);
        Socket webserver = new Socket(rh.AddressList[0].AddressFamily, SocketType.Stream, ProtocolType.IP);
        webserver.Connect(new IPEndPoint(rh.AddressList[0], rport));
        byte[] databytes = Encoding.ASCII.GetBytes(data);
        webserver.Send(databytes, databytes.Length, SocketFlags.None);
        Debug.Print("SENT TO SERVER. WILL NOW RELAY: " + data);

        //START RELAY
        buffer = new byte[2048];
        rec = 0;
        data = "";
        do
        {
            transferred = 0;
            do
            {
                rec = webserver.Receive(buffer, buffer.Length, SocketFlags.None);
                Debug.Print("RECEIVED FROM WEBSERVER[" + rec.ToString() + "]: " + Encoding.ASCII.GetString(buffer, 0, rec));

                sent = client.Send(buffer, rec, SocketFlags.None);
                Debug.Print("SENT TO CLIENT[" + sent.ToString() + "]: " + Encoding.ASCII.GetString(buffer, 0, rec));
                transferred += rec;
                //data += Encoding.ASCII.GetString(serverbytes, 0, rec);
            } while (rec == buffer.Length);

            Debug.Print("loop-1 finished");

            if (transferred == 0)
                break;

            transferred = 0;
            do
            {
                rec = client.Receive(buffer, buffer.Length, SocketFlags.None);
                Debug.Print("RECEIVED FROM CLIENT: " + Encoding.ASCII.GetString(buffer, 0, rec));

                sent = webserver.Send(buffer, rec, SocketFlags.None);
                Debug.Print("SENT TO WEBSERVER[" + sent.ToString() + "]: " + Encoding.ASCII.GetString(buffer, 0, rec));
                transferred += rec;
            } while (rec == buffer.Length);
            Debug.Print("loop-2 finished");

        } while (transferred > 0);
        Debug.Print("LOOP ENDS. EXITING THREAD");

    }
    catch (Exception ex)
    {
        Debug.Print("Error occured: " + ex.Message);
    }
回复