ソケットを使用していくつかのテストを実行していましたが、奇妙な動作が発生しました。ServerSocketは、50番目のクライアントソケットが接続した後、次のソケットが開かれる前にそのクライアントソケットが閉じられていても、遅延が発生しても接続を拒否します。接続間に追加されました。
次のプログラムは私の実験的なコードであり、現在の状態では例外をスローせず、正常に終了します。ただし、Socket[] clients
の配列サイズが50を超えて増加した場合、50番目の接続後に接続しようとするクライアントソケットはサーバーソケットによって拒否されます。
質問:50がサーバーソケットによってソケット接続が拒否されるカウントであるのはなぜですか?
public static void main(String[] args) {
try (ServerSocket server = new ServerSocket(2123)) {
Socket[] clients = new Socket[50];
for (int i = 0; i < clients.length; i++) {
clients[i] = new Socket("localhost", 2123);
System.out.printf("Client %2d: " + clients[i] + "%n", i);
clients[i].close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
別の50個のソケットが別のローカルサーバーに接続するテストを実行しましたが、100個のソケットを開いたり閉じたりしても問題は発生しなかったため、サーバーソケットが接続を拒否しており、クライアントソケットを開く制限はないと推測しましたが、同時に接続されていないのに、サーバーソケットが50接続に制限されている理由を見つけることができませんでした。
それはすべて JavaDoc にあります:
着信接続指示(接続要求)の最大キュー長は50に設定されています。キューがいっぱいになったときに接続指示が到着すると、接続は拒否されます。
どうやらあなたのServerSocket
は接続を決して受け入れず、ただ聞くだけです。 accept()
を呼び出して接続の処理を開始するか、バックログキューのサイズを増やす必要があります。
new ServerSocket(port, 100)
50はbacklog
のデフォルト値です
http://docs.Oracle.com/javase/1.4.2/docs/api/Java/net/ServerSocket.html#ServerSocket%28int%29
着信接続指示(接続要求)の最大キュー長は50に設定されています。キューがいっぱいになったときに接続指示が到着すると、接続は拒否されます。
@TomaszNurkiewiczの回答に従って、機能する例を次に示します。
import Java.net.*;
import Java.util.concurrent.atomic.AtomicBoolean;
public class SockTest{
public static void main(String[] args) {
final AtomicBoolean shouldRun = new AtomicBoolean(true);
try {
final ServerSocket server = new ServerSocket(2123);
Thread serverThread = new Thread(){
public void run() {
try {
while(shouldRun.get()) {
Socket s = server.accept();
s.close();
Thread.sleep(1);
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
};
serverThread.start();
Socket[] clients = new Socket[150];
for (int i = 0; i < clients.length; i++) {
clients[i] = new Socket("localhost", 2123);
System.out.printf("Client %2d: " + clients[i] + "%n", i);
clients[i].close();
}
shouldRun.set(false);
} catch (Exception e) {
e.printStackTrace();
} finally {
shouldRun.set(false);
}
}
}
あなたが見るかもしれない2つのこと