2

ソケットを使用して C# で単純なプロキシ サーバーをコーディングしようとしています (GET のみの atm で動作)。以下のコードは「動作」します。実行中のプロキシを介して Web ページを表示しますが、ほとんどの場合遅く、常に終了します。対処方法がわからないソケット例外...参照

class ProxyServer {
    static void Main(string[] args) {
        const int DEFAULT_PORT_NO = 27015;
        int port = -1;
        if(args.Length > 0 && args[0] != null) {
            port = Int32.Parse(args[0]); 
        } else if(port == -1) {
            port = DEFAULT_PORT_NO;
        }

        const int BACKLOG = 10;
        Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPAddress ipAddress = IPAddress.Loopback;
        IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
        listener.Bind(localEndPoint);
        listener.Listen(BACKLOG);
        Console.WriteLine(localEndPoint.ToString() + " Listening...\n");

        while(true) {
            Socket listenSocket = listener.Accept();
            RequestHandler requestHandler = new RequestHandler(listenSocket);
            Thread requestThread = new Thread(new ThreadStart(requestHandler.handle));
            requestThread.Start();
        }
    }
}

class RequestHandler {
    private Socket serverSocket;

    public RequestHandler(Socket s) {
        serverSocket = s;
    }

    public void handle() {
        string header = getHeader(serverSocket);
        string host = getHost(header);
        Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPAddress[] addresslist = Dns.GetHostAddresses(new Uri(host).Host);
        IPEndPoint remoteEndPoint = new IPEndPoint(addresslist[0], new Uri(host).Port);
        clientSocket.Connect(remoteEndPoint);
        sendRequest(clientSocket, header);

        header = getHeader(clientSocket);
        sendRequest(serverSocket, header);
        const int BUFFER_SIZE = 1024;
        byte[] buffer = new byte[BUFFER_SIZE];
        int receivedBytes = clientSocket.Receive(buffer);
        while(receivedBytes > 0) {
            serverSocket.Send(buffer, receivedBytes, SocketFlags.None);
            receivedBytes = clientSocket.Receive(buffer);
        }

        serverSocket.Shutdown(SocketShutdown.Both);
        serverSocket.Close();
    }

    string getHeader(Socket s) {
        string header = "";
        while(true){
            byte[] bytes = new byte[1];
            int bytesRec = s.Receive(bytes);
            header += System.Text.Encoding.ASCII.GetString(bytes, 0, bytesRec);
            if (header.IndexOf("\r\n\r\n") > -1 || header.IndexOf("\n\n") > -1){
                break;
            }
        }
        return header;
    }

    string getHost(String h) {
        return h.Split(new char[] {'\n'})[0].Split(new char[] {' '})[1];
    }

    void sendRequest(Socket s, string h) {
        byte[] bytesSent = System.Text.Encoding.ASCII.GetBytes(h);
        s.Send(bytesSent, bytesSent.Length, SocketFlags.None);
    }

}

ポインタは素晴らしいでしょう...

4

0 に答える 0