2014-11-05 74 views
0

我正在開發一個簡單的Java消息傳遞程序。在開始處理更復雜的功能之前,我希望基本系統能夠正常工作。目前Java - 客戶端連接出錯

  1. 多個客戶端可以連接
  2. 多個客戶端可以使服務器接收
  3. 服務器關閉連接客戶端時終止

該代碼尤其顯得是什麼讓發送消息錯誤。它是我的ClientThread.java線程中的run()方法(實現可運行)。此線程用於處理來自服務器的傳入消息(發送消息正常工作)。

import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.net.Socket; 

import javafx.application.Platform; 
import javafx.scene.Scene; 
import javafx.scene.text.Text; 
import javafx.stage.Stage; 


public class ClientThread implements Runnable{ 
    private Socket server; 
    private DataInputStream in; 
    private DataOutputStream out; 
    public Text msgContent; 
    public void login(Stage stage, Scene main, String username, String password, String portString, String host) { 
    try { 
     int port = Integer.parseInt(portString); 
     this.server = new Socket(host, port); 

     this.in = new DataInputStream(server.getInputStream()); 
     this.out = new DataOutputStream(server.getOutputStream()); 
     stage.setScene(main); 
     Platform.runLater(new ClientThread()); 
    } 
    catch (NumberFormatException e) { 
     System.out.println("Invalid Port"); 
     return; 
    } 
    catch (IOException e) { 
     System.out.println("Error Connecting to Server"); 
     return; 
    } 
} 
public void run() { 
    String msg = ""; 

    try { 

     while (true) { 
      msg = in.readUTF(); //This line gives Errors 
      System.out.println("Read message from server"); 
      msgContent.setText(msgContent.getText() + msg + "\n"); 
      System.out.println("Added message from server to view"); 
     } 

    } 
    catch(Exception ioe) { 
     ioe.printStackTrace(); 
     System.out.println("Failed to read message from server and add to view."); 
    } 

} 
public void sendMsg(String msg) { 
    try { 
     out.writeUTF(msg); 
    } catch (Exception ioe) { 
     ioe.printStackTrace(); 
    } 
} 
} 

請注意,msgContent是我的JavaFX前端和服務器的inputStream中的Text對象。我的完整代碼是here。我得到的錯誤是

顯示java.lang.NullPointerException 在ClientThread.run(ClientThread.java:42) 在com.sun.javafx.application.PlatformImpl $ 6 $ 1.run(來源不明) 在com.sun.javafx.application.PlatformImpl $ 6 $ 1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.application.PlatformImpl $ 6.run(Unknown Source) at com.sun.glass.ui.InvokeLaterDispatcher $ Future.run(未知源) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication。訪問300美元(未知來源) at com.sun.glass.ui.win.WinApplication $ 4 $ 1.run(Unknown Source) at java.lang.Thread.run(未知來源) 未能從服務器讀取消息並添加到視圖中。

另請注意,我使用Platform.runLater()來運行此方法。我想知道如何解決上述錯誤,以便我的代碼工作。提前致謝。空指針異常的

+1

'in'null?我們從來沒有看到它的定義或聲明。 – Wug 2014-11-05 22:48:36

+0

編號'in'不爲空。試試[GitHub Page](http://www.github.com/xv435/JavaMSG)來查看整個程序。 – xv435 2014-11-05 22:59:46

+0

在問題中內嵌的[mvce](http://stackoverflow.com/help/mcve)比鏈接到異地資源要好。 – jewelsea 2014-11-05 23:01:10

回答

1

原因

in爲空。發生

你NullPointerException異常,因爲在這個叫你創建ClientManager類的新實例:Platform.runLater(new ClientThread());,所以它不會使用ClientManager您在其中初始化inout成員的現有實例。相反,您可以使用Platform.runLater(this);來擺脫NullPointerException。

然而,你的代碼有其他問題...

不正確的並行編程

你都掛了JavaFX應用程序線程將停止從渲染或響應UI輸入您的應用程序。永遠不要等待JavaFX應用程序線程。

之一來完成你正在試圖做的方法是使用JavaFX concurrency utilities,特別是Task

在自己的線程上運行任務,然後它可以循環,永久接受輸入,它不會阻塞你的UI線程。您可以(也許)使您的線程成爲非守護線程,以便在所有其他守護程序線程完成時自動退出。您可以使用Platform.runLater將輸入提供回您的UI。但是,對於您想要更新某些消息文本的簡單示例,您可以調用updateMessage(請注意,由於Task類會爲您處理這種類型的細節,因此不需要調用Platform.runLater)。要更新消息標籤,可以將其文本屬性綁定到任務的消息屬性。有些示例說明如何在Task javadoc中執行此操作。

+0

感謝您的回答。 – xv435 2014-11-05 23:18:34

+0

查看此主題的任何人都可能想要查看[此處](https://gist.github.com/jewelsea/2774481)作爲此問題作者的示例。 – xv435 2014-11-06 01:24:16