0

ブラウザと Web の間で要求と応答を中継する Web プロキシ サーバーを Java で実装しようとしています。現在のセットアップでは、指定したポートですべてのページ リクエストを localhost に送信するようにブラウザを取得し、プロキシはそのポートで着信リクエストをリッスンしています。

全体がスレッド化されているため、複数のリクエストを同時に処理できます。コードは次のようになります。

   private void startProxy(int serverPort){

    try {
        // create a socket to listen on browser requests
        ServerSocket servSocket = new ServerSocket(serverPort);

        while(true) {
            // create a thread for each connection
            ProxyThread thread = new ProxyThread(servSocket.accept());
            thread.start();
        }
    } catch (IOException e) {}
   }

   class ProxyThread extends Thread {

    private Socket client;
    private Socket server;

    public ProxyThread(Socket client) {
        this.client = client;
        server = new Socket();
    }

    public void run() {
        // passes on requests and responses here
    }

html/css/js に対する 20 の異なるリクエストを含むページを読み込もうとすると、18 ~ 19 のスレッドしか作成されず、その過程でいくつかのリクエストが失われることがあります。ほとんどの場合、js リソースまたは画像のリクエストはドロップされ、ブラウザによって行われた最後のリクエストではないため、リソース不足の問題ではありません。

Wireshark を使用すると、失われた要求がローカルホストに到達することを確認できます。そのため、何らかの理由で ServerSocket.accept() は実際には接続を受け入れません。これが発生する特定の理由はありますか? それとも、私のコードが何らかの形で間違っているのでしょうか?

編集

これが run() の本体です

     try {
            BufferedReader clientOut = new BufferedReader(
                    new InputStreamReader(client.getInputStream()));
            OutputStream clientIn = client.getOutputStream();

            // assign default port to 80
            int port = 80;
            String request = "";
            // read in the first line of a HTTP request containing the url
            String subRequest = clientOut.readLine();
            String host = getHost(subRequest);

            // read in the rest of the request
            while(!subRequest.equals("")) {
              request += subRequest + "\r\n";
              subRequest = clientOut.readLine();
            }
            request += "\r\n";
            try {
                server.connect(new InetSocketAddress(host, port));
            } catch (IOException e) {
                String errMsg = "HTTP/1.0 500\nContent Type: text/plain\n\n" + 
                "Error connecting to the server:\n" + e + "\n";
                 clientIn.write(errMsg.getBytes());
                 clientIn.flush();
            }

            PrintWriter serverOut = new PrintWriter(server.getOutputStream(), true);
            serverOut.println(request);
            serverOut.flush();

            InputStream serverIn = server.getInputStream();

            byte[] reply = new byte[4096];
            int bytesRead;
            while ((bytesRead = serverIn.read(reply)) != -1) {
               clientIn.write(reply, 0, bytesRead);
               clientIn.flush();
            }


            serverIn.close();
            serverOut.close();

            clientOut.close();
            clientIn.close();

            client.close();
            server.close();
        } catch(IOException e){
            e.printStackTrace();
        }
4

1 に答える 1