2014-11-05 2 views
0

간단한 Java 메시징 프로그램을 작성 중입니다. 좀 더 복잡한 기능에 대한 작업을 시작하기 전에 기본 시스템을 작동시키고 싶습니다. 현재Java - 연결시 클라이언트 제공 오류

  1. 여러 클라이언트는 서버가 서버 클라이언트가있을 때 연결을 닫습니다 특히이 코드는주고 무엇을 것으로 보인다

종료

  • 수신 메시지를 보낼 수 있습니다
  • 여러 클라이언트를 연결할 수 있습니다 오류. ClientThread.java 스레드 (runnable을 구현)에서 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입니다. 나는 점점 오전 오류가에

    ClientThread.run (ClientThread.java:42)에서 java.lang.NullPointerException이 com.sun.javafx.application.PlatformImpl $ (6) $ 1.run (알 수없는 소스)에서 입니다 com.sun.javafx.application.PlatformImpl $ 6 $ 1.run (알 수없는 소스)at java.security.AccessController.doPrivileged (네이티브 메소드) at com.sun.javafx.application.PlatformImpl $ 6.run (알 수없는 소스) at com.sun.glass.ui.InvokeLaterDispatcher $ Future.run (알 수없는 소스) com.sun.glass.ui.win.WinApplication._runLoop (네이티브 메소드) com.sun.glass.ui.win.WinApplication. 액세스 $ 300 (알 수없는 출처) com.sun.glass.ui.win.WinApplication $ 4 $ 1.run (알 수없는 소스) java.lang.Thread.run (알 수없는 소스) 서버에서 메시지를 읽지 못하고보기에 추가하지 못했습니다.

    또한이 메서드를 실행하려면 Platform.runLater()를 사용하고 있습니다. 위의 오류를 수정하여 내 코드가 작동하는 방법을 알고 싶습니다. 미리 감사드립니다. NullPointer 예외

  • +1

    'in'은 null입니까? 정의되거나 선언 된 부분을 결코 볼 수 없습니다. – Wug

    +0

    아니요. 'in'이 (가) null이 아닙니다. 전체 프로그램을 보려면 [GitHub Page] (http://www.github.com/xv435/JavaMSG)를 시도하십시오. – xv435

    +0

    질문에 인라인으로 게시 된 [mvce] (http://stackoverflow.com/help/mcve)는 오프 사이트 리소스에 대한 링크보다 낫습니다. – jewelsea

    답변

    1

    원인

    in 널이다. 이 전화에 당신이 ClientManager 클래스의 새 인스턴스를 만들 수 있기 때문에

    귀하의 NullPointerException가 발생 Platform.runLater(new ClientThread());를, 그래서 당신이 inout 회원 초기화가되는 ClientManager의 기존 인스턴스를 사용하지 않습니다. 대신 Platform.runLater(this);을 사용하여 NullPointerException을 제거 할 수 있습니다.

    그러나 코드는 ... 다른 문제가

    잘못된 동시 프로그래밍

    당신은 렌더링 또는 UI 입력에 응답에서 응용 프로그램을 중지합니다 자바 FX 애플리케이션 스레드를 걸려있다. 절대로 JavaFX 응용 프로그램 스레드를 기다리지 마십시오.

    시도하려는 작업을 수행하는 한 가지 방법은 JavaFX concurrency utilities, 특히 Task을 사용하는 것입니다.

    자체 스레드에서 작업을 실행하면 루프가 반복되어 입력을 영원히 받아 들일 수 있으며 UI 스레드가 차단되지 않습니다. 스레드를 비 데몬 스레드로 만들 수 있으므로 다른 모든 데몬 스레드가 완료 될 때 자동으로 종료됩니다. Platform.runLater를 사용하여 UI에 입력을 다시 공급할 수 있습니다. 그러나 간단한 예제에서 일부 메시지 텍스트를 업데이트 할 위치를 제공하는 대신 updateMessage을 호출 할 수 있습니다. Task 클래스는 이러한 세부 정보를 처리하므로 Platform.runLater 호출이 필요하지 않습니다. 메시지 레이블을 업데이트하려면 텍스트 속성을 작업의 message 속성에 바인딩 할 수 있습니다. Task javadoc에서이를 수행하는 방법의 예가 있습니다.

    +0

    답변 해 주셔서 감사합니다. – xv435

    +0

    이 스레드를 찾는 사람은이 질문의 작성자가 예를 들어 [여기] (https://gist.github.com/jewelsea/2774481)를보고 싶을 수 있습니다. – xv435

    관련 문제