2016-11-03 19 views
7

Javaで単純なクライアント/サーバーアプリケーションを実装しようとしています。Java while(true)ループはスレッド内で一度だけ実行されます

ここではコードです:

Client.java

public class Client implements Runnable { 
    private String hostName; 
    private int portNumber; 
    private String message; 

    private Socket socket; 
    private PrintWriter writer; 
    private BufferedReader reader; 

    public Client(String hostName, int portNumber, String message) { 
     this.hostName = hostName; 
     this.portNumber = portNumber; 
     this.message = message; 
    } 

    public void connect() { 
     try { 
      socket = new Socket(hostName, portNumber); 
      writer = new PrintWriter(socket.getOutputStream(), true); 
      reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

      writer.println(message); 
     } catch (UnknownHostException e) { 
      System.err.println("Could not resolve the host name '" + hostName + "'."); 
     } catch (IOException e) { 
      System.err.println("Could not get the I/O for the connection to '" + hostName + "'."); 
     } 
    } 

    private void listenForMessages() { 
     while (true) { 
      try { 
       System.out.println("In loop!"); 
       String line; 
       while ((line = reader.readLine()) != null) { 
        System.out.println(line); 
       } 
      } catch (IOException e) { 
       System.err.println(e.getMessage()); 
      } 
     } 
    } 

    public void run() { 
     connect(); 
     listenForMessages(); 
    } 
} 

Server.java

public class Server implements Runnable { 
    private int portNumber; 
    private String message; 

    private ServerSocket serverSocket; 
    private Socket clientSocket; 
    private PrintWriter writer; 
    private BufferedReader reader; 

    public Server(int portNumber, String message) { 
     this.portNumber = portNumber; 
     this.message = message; 
    } 

    private void listen() { 
     try { 
      serverSocket = new ServerSocket(portNumber); 
     } catch (IOException e) { 
      System.err.println(e.getMessage()); 
     } 

     while (true) { 
      try { 
       clientSocket = serverSocket.accept(); 
       writer = new PrintWriter(clientSocket.getOutputStream(), true); 
       reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 

       String line; 
       while ((line = reader.readLine()) != null) { 
        System.out.println(line); 
       } 

       writer.println(message); 
      } catch (IOException e) { 
       System.err.println(e.getMessage()); 
       break; 
      } 
     } 
    } 

    public void run() { 
     listen(); 
    } 
} 

そして、これが主なクラスです:

public class Test { 
    public static void main(String[] args) { 
     Client client = new Client("localhost", 4444, "Hello from client!"); 
     Server server = new Server(4444, "Hello from server!"); 

     Thread serverThread = new Thread(server); 
     serverThread.start(); 

     Thread clientThread = new Thread(client); 
     clientThread.start(); 
    } 
} 

のロジックはコードは単純です:クライアントとSEの両方rverはwhile(true)ループ内のメッセージを待っています。

listenメソッド内のwhileループがうまく実行されます。しかし、listenForMessagesメソッドの内部では、ループは1回だけ実行されるようです。私は画面に印刷された "In Loop"を見るだけです。

問題の原因を特定できますか?

ありがとうございます!

+0

は、デバッガを使用することはできますか? –

+0

さて、私はプレーンテキストエディタを使用していますが、コマンドラインからデバッガを使用する方法がわかりません。 –

+2

サイドノート:例外を見落とさないと確信していますか?あなたは、あなたのコードは単に**例外**の印刷**です。しかし、それは単にそれが何をしているのかを継続しようとします。例外については**失敗**を考慮してください! – GhostCat

答えて

6

ただし、listenForMessagesメソッドの内部では、ループは が1回だけ実行されているようです。私は画面に印刷された "In Loop"を見るだけです。

ループが、それは全体のラインを受け取り、ここにあなたがServerのコードをチェックすると、それは最初に読み込んで、それまでreader.readLine()は、現在のスレッドの待機を行いますので、それは単に一度だけ実行されるため、実際にそうではありませんreader.readLine()はストリームの終わりにnullを返すだけなので、ソケットがこのケースで閉じられるときは無限ループで読み込みます。あなたは、クライアントとサーバーの間でピンポンのいくつかの種類を実装する場合

、単にその後、片側に書き込み、読み書きや読み出しなど次の他の側面:

Clientコード:

public void connect() { 
    try { 
     socket = new Socket(hostName, portNumber); 
     writer = new PrintWriter(socket.getOutputStream(), true); 
     reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

    } catch (UnknownHostException e) { 
     System.err.println("Could not resolve the host name '" + hostName + "'."); 
    } catch (IOException e) { 
     System.err.println(
      "Could not get the I/O for the connection to '" + hostName + "'." 
     ); 
    } 
} 

private void listenForMessages() { 
    while (true) { 
     try { 
      System.out.println("In loop!"); 
      // Write the message for the server 
      writer.println(message); 
      // Read the message from the server 
      System.out.println(reader.readLine()); 
     } catch (IOException e) { 
      System.err.println(e.getMessage()); 
     } 
    } 
} 

Serverコード:

while (true) { 
    try { 
     clientSocket = serverSocket.accept(); 
     writer = new PrintWriter(clientSocket.getOutputStream(), true); 
     reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 

     while (true) { 
      // Read the message from the client 
      System.out.println(reader.readLine()); 
      // Write the message for the client 
      writer.println(message); 
     } 


    } catch (IOException e) { 
     System.err.println(e.getMessage()); 
     break; 
    } 
} 

出力:

In loop! 
Hello from client! 
Hello from server! 
In loop! 
Hello from client! 
Hello from server! 
... 
+1

ありがとうございました!今はっきりしている。 –

関連する問題