2017-02-01 7 views
0

からのメッセージを受信します。同時に私はクライアントから受け取ったメッセージを読みたい。は、私がクライアントに接続書かれた次のサーバーを持っているクライアント

私はこのソケットプログラミングをイベントハンドラ経由で数年前に別の言語で行っていましたが、ここでは別のアプローチが必要になると思われます。

私の質問です:このタスクに別のスレッドが必要ですか?例えば、ノンブロッキングモード?

+0

あなたは別のスレッドを必要とするだろうか?もちろんはい。他の選択肢はありません。 –

+0

@HovercraftFullOfEels:同じスレッドを持つ非ブロッキングソケットのようなものは本当にありませんか? – user963241

+0

スレッドを使用するだけです。それはまさにそのためのものです。 –

答えて

1

をチェックし、あなたがインターネット上でマルチスレッド・サーバーのための複数の実装を見つけることができますスレッドプールを作成し、ThreadPoolの

Socket clientSocket = serverSocket.accept(); 
threadPool.submit(new ClientTask(clientSocket)); 

に新しいタスクとしてclientSocketを提出することができ私の質問です:このタスクのために別のスレッドが必要でしょうか?

1つの方法は、クライアント接続ごとにスレッドを使用することです。アプリケーションメソッドは、ポートをリッスンする無限ループでサーバーを実行します。接続が要求されると、サービスを行うために新しいスレッドが生成され、ただちにリスニングに戻ります。

ServerSocket listener = new ServerSocket(9898); 
try { 
    while (true) { 
     new Handler(listener.accept(), clientNumber++).start(); 
    } 
} finally { 
    listener.close(); 
} 

特定のソケットでリクエストを処理するスレッド。

private static class Handler extends Thread { 
    private Socket socket; 
    private int clientNumber; 

    public Handler(Socket socket, int clientNumber) { 
     this.socket = socket; 
     this.clientNumber = clientNumber; 
    } 

    public void run() { 
     try { 
      BufferedReader in = new BufferedReader(
        new InputStreamReader(socket.getInputStream())); 
      PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 

      while (true) { 
       String input = in.readLine(); 
       ... 
      } 
     } catch (IOException e) { 
     } finally { 
      try { 
       socket.close(); 
      } catch (IOException e) { 
       log("Couldn't close a socket, what's going on?"); 
      } 
     } 
    } 
} 

代替例がありますノンブロッキングモード?

ノンブロッキングソケットチャネルの場合、サーバソケットは特定の操作を行うためにセレクタに登録する必要があります。デフォルトでは、サーバーソケットチャネルはブロッキングチャネルです。非ブロックチャネルにするには、次のように設定します。

channel.configureBlocking(false); 

ノンブロッキングサーバープログラムは次のようになります...

InetAddress hostIPAddress = InetAddress.getByName("localhost"); 
int port = 19000; 
Selector selector = Selector.open(); 
ServerSocketChannel channel = ServerSocketChannel.open(); 
channel.configureBlocking(false); 
channel.socket().bind(new InetSocketAddress(hostIPAddress, port)); 
channel.register(selector, SelectionKey.OP_ACCEPT); 

while (true) { 
    Set keys = selector.selectedKeys(); 
    ... 
} 

のようになります。非ブロッククライアントプログラム...

InetAddress serverIPAddress = InetAddress.getByName("localhost"); 
InetSocketAddress serverAddress = new InetSocketAddress(
    serverIPAddress, 19000); 
Selector selector = Selector.open(); 
SocketChannel channel = SocketChannel.open(); 
channel.configureBlocking(false); 
channel.connect(serverAddress); 
int operations = SelectionKey.OP_CONNECT | SelectionKey.OP_READ 
    | SelectionKey.OP_WRITE; 
channel.register(selector, operations); 

while (true) { 
    if (selector.select() > 0) { 
    Set keys = selector.selectedKeys(); 
    ... 
    } 
} 
channel.close();