2015-08-30 44 views
0

我是新來的Java,我正在嘗試學習線程和套接字。所以決定在官方的java教程之後製作一個簡單的客戶端 - 我的想法很簡單 - 服務器等待連接,如果出現,它使用新套接字,輸入和輸出創建新線程。客戶端 - >建立連接;帶有套接字,輸入,輸出和stdIn的新線程(讀取行並將其發送到服務器之後)。但是有一些錯誤(不知道爲什麼)用我的代碼。連接已建立,沒有例外。有人可以解釋爲什麼不工作,以及如何解決它?也可能你對代碼的任何建議(可能它不是與最佳實踐之類的東西):在Java中的簡單客戶端服務器應用程序中讀/寫

Client side: 

public class Client { 
    private BufferedReader reader; 
    private Socket sock; 
    private PrintWriter writer; 

public static void main(String[] args) { 
    Client client = new Client(); 
    client.go(); 
} 

public void go() { 
    setUpNetworking(); 

} 

private void setUpNetworking() { 
    try{ 
     sock = new Socket("127.0.0.1", 5000); 
     System.out.println("Network established"); 

     ServerThread serverThread= new ServerThread(sock); 
     serverThread.start(); 

     System.out.println("Type your message: "); 
    } catch (IOException e) { 
     System.out.println("Problem with establishing the network: " + e); 
    } 
} 

class ServerThread extends Thread { 
    Socket socket; 
    PrintWriter out; 
    BufferedReader in; 
    BufferedReader stdIn; 

    ServerThread(Socket socket) { 
     this.socket = socket; 

     try{ 
      out = new PrintWriter(socket.getOutputStream()); 
      in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      stdIn = new BufferedReader(new InputStreamReader(System.in)); 
     }catch (IOException e) { 
      System.out.println("Problem with trying to read/write to server: " + e); 
     } 
    } 
    @Override 
    public void run() { 
     String fromServer; 
     String fromClient; 
     while(true){ 
      try{ 

       if((fromServer = in.readLine()) != null) System.out.println(" " + fromServer); 
       else if((fromClient = stdIn.readLine()) != null) out.println(fromClient); 

      }catch(Exception e) { 
       System.out.println("msg exception: " + e); 
      } 

     } 
    } 
} 

} 

服務器端:

public class Server { 
    //Run server until keepGoing = false 
    private boolean keepGoing = true; 



    public static void main(String[] args) { 
     Server server = new Server(); 
     server.go(); 
    } 

    public void go() { 

      try { 
       ServerSocket serverSocket = new ServerSocket(5000); 

       while(keepGoing) { 

        Socket clientSocket = serverSocket.accept(); 
        ClientThread t = new ClientThread(clientSocket); 
        t.start(); 
       } 
      } catch (IOException e) { 
       System.out.println("Problem with socket/network: " + e); 
      } 
    } 

    class ClientThread extends Thread { 
     Socket clientSocket; 
     PrintWriter out; 
     BufferedReader in; 

     ClientThread(Socket clientSocket) { 
      this.clientSocket = clientSocket; 

      try{ 
       out = new PrintWriter(clientSocket.getOutputStream()); 
       in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
      } catch (IOException e) { 
       System.out.println("Problem with creating in/out: " + e); 
      } 
     } 

     @Override 
     public void run() { 
      String message; 
      while(keepGoing) { 
       try{ 
        message = in.readLine(); 
        out.println(message); 
        System.out.println(message); 

       } catch (IOException e){ 
        System.out.println("Exception while try to read line: " + e); 
       } 

      } 
     } 
    } 

} 

PS我已經改變了一下代碼 - 而不是的ClientThread類,我做了新的runnable類,並將該變量傳遞給線程類。受此問題啓發:"implements Runnable" vs. "extends Thread"

回答

1

我認爲問題在於服務器和客戶端都在等待任何輸入。服務器:

message = in.readLine(); 

客戶:在fromServer = in.readLine()部分

if((fromServer = in.readLine()) != null) 
    System.out.println(" " + fromServer); 
else if((fromClient = stdIn.readLine()) != null) 
    out.println(fromClient); 

但已經在客戶端的代碼塊,所以它永遠不會從標準,從而讀什麼都不會被髮送到服務器。

您可以將您嘗試從標準讀取方式移動到setUpNetworking方法中,緊接在System.out.println("Type your message: ");之後。構建循環有你退出,如果用戶鍵入「退出」或「跳槽」或類似的東西:

BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); 
String read = ""; 
do { 
    read = stdIn.readLine(); 
    System.out.println("Read from stdin: " + read); 
    serverThread.send(read); 

} 
while (!read.equals("exit")); 

ServerThread.send()方法很簡單:

void send(String string) { 
    System.out.println("Sending to server: " + string); 
    out.println(string); 
} 

然而,使其工作,你要麼寫出來後手動刷新流,或者使用下面的構造函數:

out = new PrintWriter(socket.getOutputStream(), true); 

PrintWriter's JavaDoc:true意味着自動沖水的換行符。

我測試了這個設置,它爲我工作。我能夠從客戶端發送一些東西到服務器。

但是,這只是第一步。我將爲客戶端和服務器實現讀寫作爲單獨的線程。並沒有優雅地關閉實現的套接字。一個更完整但簡單的例子可以在Oracle上找到。

+0

Sry基因,但好像如果我沒有得到做什麼或不工作的方式:/這聽起來很容易與線程和插座的工作,但它確實很難,我:/ –

+0

沒有概率的,但我需要更多的信息來進一步幫助你。 1)你有沒有嘗試移動'fromServer = in.readLine()'行,並在事後工作?我會在這裏編輯我的答案,使其更加冗長。 2)你在線程/套接字的確切問題在哪裏?如果您有更具體的問題,幫助更容易。 – beosign

+0

我試圖改變線條,並使其成爲這樣:'if((fromClient = stdIn.readLine())!= null)out.println(fromClient); if((fromServer = in.readLine())!= null)System.out。println(「」+ fromServer);'並且不起作用。我認爲這個問題確實是在聆聽事件,但卻找不到在哪裏。也許不能使用正確的調試方式,但在客戶端知道一切正常 - 我打字輸出,然後在第二個檢查傳入流沒有任何反應。無法查看我的流是否轉到服務器,然後返回到客戶端:/ –

相關問題