2016-09-16 63 views
0

該練習程序的目標僅僅是允許客戶端連續發送用戶通過輸入並按下輸入鍵並將其輸出到控制檯的消息串。第一次,Server.java中的String messageFromClient = in.readLine();似乎阻塞(調試器不會讓我離開)。然而,在發送消息如「你好」之後,它會繼續無阻擋地運行。while循環僅在第一個循環停止,然後繼續無限期地運行

我一直在尋找這個了幾個小時,但我想我只是沒有看到解決方案的正確位置。

此鏈接Java InputStream blocking read可能是我發現的最接近的東西,可以幫助我。

Client.java

import java.io.*; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.io.OutputStreamWriter; 
import java.net.*; 
import java.net.InetAddress; 
import java.util.Scanner; 

public class Client { 
    static Socket connectionToServer; 
    public static void main(String[] args) { 
     try{ 
      connectionToServer = new Socket("192.168.1.66", 6969); 
      InetAddress inetAddress = connectionToServer.getInetAddress(); 
      System.out.print(
        "Connection successful" + 
        "Connected to " + inetAddress.getHostAddress() + 
        "at " + inetAddress.getHostName() + "\n" 
      ); 

      while(true) { 
       String input = System.console().readLine(); 
       OutputStreamWriter dOut = new OutputStreamWriter(connectionToServer.getOutputStream()); 
       dOut.write(input, 0, input.length()); 
       //dOut.flush(); 
       dOut.close(); 
      } 

     } catch (IOException exception){ 
      System.out.print("Failed to create socket"); 
     } 

    } 
} 

Server.java

import java.io.*; 
import java.net.*; 

public class Server { 
    public static void main(String[] args) { 
     ServerSocket serverSocket; 
     try { 
      serverSocket = new ServerSocket(6969); 
      System.out.print("Server is up and running \n"); 
     } catch (IOException exception){ 
      serverSocket = null; 
      System.out.print("Cannot create ServerSocket"); 
     } 

     while (true){ 
      try { 
       System.out.print("Waiting from client."); 
       Socket socket = serverSocket.accept(); 
       Thread newClientSocket = new Thread(new ServerThread(socket)); 
       newClientSocket.start(); 
       System.out.print("New thread created"); 
      } catch (IOException exception){ 
       System.out.print("Failed to create socket"); 
      } 
     } 
    } 
} 
//////////////////////////////////////////////////////////// 
class ServerThread implements Runnable{ 
    private Socket socket; 
    //constructor 
    ServerThread(Socket socket){ 
     System.out.print("I am a new thread"); 
     this.socket = socket; 
    } 

    public void run(){ 
     while(true){ 
      try{ 
       System.out.print("Waiting for input."); 
       InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream()); 
       BufferedReader in = new BufferedReader(inputStreamReader); 
       String messageFromClient = in.readLine(); 
       System.out.print(messageFromClient); 
      } catch (IOException exception) { 
       System.out.print(exception); 
       break; 
      } 
     } 
    } 
} 

回答

0

你不應該構建每次循環迭代新BufferedReader,因爲BufferedReader將嘗試完全填充緩衝區,並可能在第一行結束時讀取數據 - 並且數據將丟失,因爲您正在構建一個新的BufferedReader只有它的第一行。

將BufferedReader的構建移出循環,這應該會對您有所幫助。另外,請確保在完成後關閉套接字。

public void run() { 
    try { 
     try { 
      InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream()); 
      BufferedReader in = new BufferedReader(inputStreamReader); 
      while (true) { 
       System.out.print("Waiting for input."); 
       String messageFromClient = in.readLine(); 
       System.out.print(messageFromClient); 
      } 
     } finally { 
      socket.close(); 
     } 
    } catch (IOException exception) { 
     System.out.print(exception); 
     // TODO: handle exception 
    } 
} 

在發送端,你不應該關閉套接字的OutputStream中的每一行,因爲一旦你關閉它,你不能用它了。並且您應該在字符串後面向服務器發送換行符,因爲Console.readLine()方法未將其包含在其返回值中。

 OutputStreamWriter dOut = new OutputStreamWriter(connectionToServer.getOutputStream()); 
     while(true) { 
      String input = System.console().readLine() + "\n"; 
      dOut.write(input, 0, input.length()); 
     } 
     dOut.close(); 
0

到Console.ReadLine()不包括終止字符。 BufferedReader.readLine()塊直到它得到一個終止換行符

更改此:

String input = System.console().readLine(); 

要這樣:

String input = System.console().readLine() + System.lineSeparator();