C# 實現一個多線程的 Web 代理服務器

n342 10年前發布 | 2K 次閱讀 C#

 
/**
C# Programming Tips & Techniques
by Charles Wright, Kris Jamsa

Publisher: Osborne/McGraw-Hill (December 28, 2001) ISBN: 0072193794 */

// Proxy.cs -- Implements a multi-threaded Web proxy server // // Compile this program with the following command line: // C:>csc Proxy.cs using System; using System.Net; using System.Net.Sockets; using System.Text; using System.IO; using System.Threading;

namespace nsProxyServer { public class ProxyServer { static public void Main (string [] args) { int Port = 3125; if (args.Length > 0) { try { Port = Convert.ToInt32 (args[0]); } catch { Console.WriteLine ("Please enter a port number."); return; } } try { // Create a listener for the proxy port TcpListener sockServer = new TcpListener (Port); sockServer.Start (); while (true) { // Accept connections on the proxy port. Socket socket = sockServer.AcceptSocket ();

                // When AcceptSocket returns, it means there is a connection. Create
                // an instance of the proxy server class and start a thread running.
                clsProxyConnection proxy = new clsProxyConnection (socket);
                Thread thrd = new Thread (new ThreadStart (proxy.Run));
                thrd.Start ();
                // While the thread is running, the main program thread will loop around
                // and listen for the next connection request.
            }
        }
        catch (IOException e)
        {
            Console.WriteLine (e.Message);
        }
    }
}

class clsProxyConnection
{
    public clsProxyConnection (Socket sockClient)
    {
        m_sockClient = sockClient;
    }
    Socket m_sockClient; //, m_sockServer;
    Byte [] readBuf = new Byte [1024];
    Byte [] buffer = null;
    Encoding ASCII = Encoding.ASCII;

    public void Run ()
    {
        string strFromClient = "";
        try
        {
            // Read the incoming text on the socket/
            int bytes = ReadMessage (m_sockClient,
                                     readBuf, ref strFromClient);
            // If it's empty, it's an error, so just return.
            // This will termiate the thread.
            if (bytes == 0)
                return;
            // Get the URL for the connection. The client browser sends a GET command
            // followed by a space, then the URL, then and identifer for the HTTP version.
            // Extract the URL as the string betweeen the spaces.
            int index1 = strFromClient.IndexOf (' ');
            int index2 = strFromClient.IndexOf (' ', index1 + 1);
            string strClientConnection =
                  strFromClient.Substring (index1 + 1, index2 - index1);

            if ((index1 < 0) || (index2 < 0))
            {
                throw (new IOException ());
            }
            // Write a messsage that we are connecting.
            Console.WriteLine ("Connecting to Site " +
                               strClientConnection);
            Console.WriteLine ("Connection from " +
                               m_sockClient.RemoteEndPoint);
            // Create a WebRequest object.
            WebRequest req = (WebRequest) WebRequest.Create
                                                 (strClientConnection);
            // Get the response from the Web site.
            WebResponse response = req.GetResponse ();
            int BytesRead = 0;
            Byte [] Buffer = new Byte[32];
            int BytesSent = 0;

            // Create a response stream object.
            Stream ResponseStream = response.GetResponseStream();

            // Read the response into a buffer.
            BytesRead = ResponseStream.Read(Buffer,0,32);
            StringBuilder strResponse = new StringBuilder("");
            while (BytesRead != 0)
            {
                // Pass the response back to the client
                strResponse.Append(Encoding.ASCII.GetString(Buffer,
                                    0, BytesRead));
                m_sockClient.Send(Buffer, BytesRead, 0);
                BytesSent += BytesRead;
                // Read the next part of the response
                BytesRead = ResponseStream.Read(Buffer, 0, 32);
            }
        }
        catch (FileNotFoundException e)
        {
            SendErrorPage (404, "File Not Found", e.Message);
        }
        catch (IOException e)
        {
            SendErrorPage (503, "Service not available", e.Message);
        }
        catch (Exception e)
        {
              SendErrorPage (404, "File Not Found", e.Message);
              Console.WriteLine (e.StackTrace);
              Console.WriteLine (e.Message);
        }
        finally
        {
            // Disconnect and close the socket.
            if (m_sockClient != null)
            {
                if (m_sockClient.Connected)
                {
                    m_sockClient.Close ();
                }
            }
        }
        // Returning from this method will terminate the thread.
    }
    // Write an error response to the client.
    void SendErrorPage (int status, string strReason, string strText)
    {
        SendMessage (m_sockClient, "HTTP/1.0" + " " +
                     status + " " + strReason + "\\r\\n");
        SendMessage (m_sockClient, "Content-Type: text/plain" + "\\r\\n");
        SendMessage (m_sockClient, "Proxy-Connection: close" + "\\r\\n");
        SendMessage (m_sockClient, "\\r\\n");
        SendMessage (m_sockClient, status + " " + strReason);
        SendMessage (m_sockClient, strText);
    }

    // Send a string to a socket.
    void SendMessage (Socket sock, string strMessage)
    {
        buffer = new Byte [strMessage.Length + 1];
        int len = ASCII.GetBytes (strMessage.ToCharArray(),
                                  0, strMessage.Length, buffer, 0);
        sock.Send (buffer, len, 0);
    }

    // Read a string from a socket.
    int ReadMessage (Socket sock, byte [] buf, ref string strMessage)
    {
        int iBytes = sock.Receive (buf, 1024, 0);
        strMessage = Encoding.ASCII.GetString (buf);
        return (iBytes);
    }
}

}

</pre>

 本文由用戶 n342 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!