13

ソケットを使用していくつかのテストを実行していたところ、いくつかの奇妙な動作に遭遇しました: ServerSocket は、50 番目のクライアント Socket がそれに接続した後、接続を拒否します。接続間に追加。

次のプログラムは私の実験的なコードで、現在の状態では例外をスローせず、正常に終了します。ただし、 の配列サイズがSocket[] clients50 を超えて増加すると、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 接続に制限されている理由を発見できませんでした。

4

4 に答える 4

16

それはすべてJavaDocにあります:

着信接続表示 (接続要求) の最大キュー長は 50 に設定されています。キューがいっぱいのときに接続表示が到着すると、接続は拒否されます。

どうやら、ServerSocket接続を受け入れることはなく、リッスンするだけです。呼び出して接続の処理を開始するか、バックログ キューのサイズaccept()を増やす必要があります。

new ServerSocket(port, 100)
于 2012-10-19T20:30:55.287 に答える
4

のデフォルト値は 50 です。backlog

http://docs.oracle.com/javase/1.4.2/docs/api/java/net/ServerSocket.html#ServerSocket%28int%29

着信接続表示 (接続要求) の最大キュー長は 50 に設定されています。キューがいっぱいのときに接続表示が到着すると、接続は拒否されます。

于 2012-10-19T20:30:28.300 に答える
2

@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);
    }

  }
}
于 2012-10-19T20:57:00.927 に答える
0

あなたが見るかもしれない2つのこと

  1. サーバーが接続を受け入れていません。
  2. サーバーは同時に多数の接続に対応できません。バックログの増加 (50 を超える) が原因である可能性があります。サーバーに再度接続する前に、ミリ秒単位の時間間隔を空けてみてください。ランプアップ接続のように。テストロードを実行したときに時間のギャップを与えることで解決しました。
于 2018-01-25T12:23:36.110 に答える