2014-11-05 104 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