ブラウザと 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();
}