5


2

受け入れたソケットをJavaで非ブロッキングにする方法

クライアントからの接続を受け入れて、その接続ソケットを別のオブジェクトに渡します。ただし、そのソケットは非ブロック化である必要があります。 私は `getChannel()。configureBlocking(false)`を使おうとしていますが、うまくいかないようです。 これは、以下のメソッドが100msごとに呼び出されるため、ノンブロッキングである必要があります。 これをブロックしないようにする他の方法はありますか? 助けてくれてありがとう!

public void checkForClients() {
  DataOutputStream out;
  DataInputStream in;
  Socket connection;
  InetAddress tempIP;
  String IP;

  try {
     connection = serverSocket.accept();
     connection.getChannel().configureBlocking(false);

     System.err.println("after connection made");

     in = new DataInputStream(connection.getInputStream());
     out = new DataOutputStream(connection.getOutputStream());
     tempIP = connection.getInetAddress();
     IP = tempIP.toString();

     System.err.println("after ip string");

     // create a new user ex nihilo
     connectedUsers.add(new ConnectedUser(IP, null, connection, in, out));


     System.err.println("after add user");
  } catch (SocketTimeoutException e) {
     System.err.println("accept timeout - continuing execution");
  } catch (IOException e) {
     System.err.println("socket accept failed");
  }
}

5 Answer


8


2つのこと

  1. なぜ使用しないのですか http://www.j2ee.me/javase/6/docs/api/java/net/ServerSocket.html [ServerSocket]接続をリッスンしている場合

  2. 複数のクライアントを受け入れたい場合は、ループを使用します。

マルチクライアントサーバーの基本構造は次のとおりです。

while (true) {
  // accept connections
  // spawn thread to deal with that connection
}

問題が `accept()`呼び出しをブロックしているなら、まさにそれが `accept()`がすることです:それは接続を待つことをブロックします。 それが問題であるならば、私はあなたが接続を受け入れるために別のスレッドを持っていることを提案します。

http://java.sun.com/docs/books/tutorial/networking/sockets/clientServer.html [ソケットのサーバー側への書き込み]を参照してください。


1


私はあなたのコードがconfigureBlocking呼び出しに到達しないで、accept呼び出しをブロックすることを期待するでしょう。

通常、ソケット接続ごとに別々のスレッドをスピンオフし、実際に接続が確立または受け入れられるまでブロックするようにします。これにより、メインスレッドはクライアント接続を待っている間、ブロック解除を続行できます。


1


ノンブロッキングソケットを探しているなら、私の提案はNIOパッケージでSelectorsとServerSocketChannelsを使うことです。


0


一般的なブロッキングソケットでは必要な可用性が得られない場合(100msごとの接続ではタイトに見えます)。 あなたはノンブロッキングソケットを見てください。 こちらはチュートリアルです。 これを容易にするためにApache MINAを見ることもできます。


0


1つの方法は、シングルスレッド環境でI / Oループ(イベントループ)を使用することです。 インスピレーションのために Deft web serverを見てください。 (特に IOLoopのstart()メソッド)