prahladyeri 0 Newbie Poster

I have written a simple and minimalist HTTP proxy server that runs on command line. In the Start() method, a TcpListener blocks until it gets a client request and creates a new thread (ThreadHandleClient method) that processes this client, fetches its url and relays data.

The trouble is in the relay logic that I want to refine. In the first inner loop, I receive all webserver data and send it to client until zero bytes are left. In second inner loop, I do vice-versa: receive all client data and send to web-server until zero bytes left. However, the code gets blocked in the beginning of second inner-loop at client.receive(). This is what I'm basically doing:

Any help will be truly appreciated. Thanks in advance.

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);
    }