2016-07-01 16 views
1

私は学校用のサーバー/クライアントアプリケーションを作成しています。java.net.SocketExceptionの原因:クライアントを閉じた後に接続がリセットされましたか?

クライアントを閉じるたびに、サーバーは 'java.net.SocketException:Connection reset'をスローします。私は、JavaFXウィンドウを閉じる前にクライアントのソケットを閉じなければならないと思いますが、どこで?あなたはどう思いますか?

私は似たような質問を見ましたが、自分のプログラムで正しく実装する方法はわかりません。

例外:

20:05:27.132 [Thread-2] ERROR OnlineBank - java.net.BindException: Address already in use: JVM_Bind 
19:51:06.580 [Thread-1] ERROR ServerHandler - java.net.SocketException: Connection reset 
19:51:06.580 [Thread-2] ERROR ServerHandler - java.net.SocketException: Connection reset 

MyProgramm:

private MyProgramm() {  
    server = new MyServer(Constants.REMOTE_PORT); 
    try 
     server.start(); 
    } catch (ClassNotFoundException | IOException e) { 
     logger.error(e);  
    } 
} 

MyServerを:

public void start() throws ClassNotFoundException, IOException { 
     try { 
      serverSocket = new ServerSocket(this.port); 

      while (true) { 
       Socket client = serverSocket.accept(); 
       logger.debug(getClass().getName() + " accepts"); 

       Thread threadHandler = new Thread(new ServerHandler(client)); 
       threadHandler.start(); 
      } 

     } finally { 
      if (serverSocket != null) { 
       serverSocket.close(); 
      } 
     } 

    } 

ServerHandler:

@Override 
    public void run() { 

     try (InputStream in = clientSocket.getInputStream(); 
       OutputStream out = clientSocket.getOutputStream(); 
       ObjectInputStream oin = new ObjectInputStream(in); 
       ObjectOutputStream oos = new ObjectOutputStream(out)) { 

      while (true) { 
       try { 
        Object receivedObject = oin.readObject(); 
        handleReceivedObject(oos, receivedObject); 

       } catch (ClassNotFoundException e) { 
        logger.error(e); 
        break; 
       } 
      } 
     } catch (IOException e) { 
      logger.error(e); 
     } 
    } 

MainClient:

public class MainClient extends Application { 
    private static Client client; 

    public static void main(String[] args) { 
     launch(args); 
     try { 
      client = new Client(); 
     } catch (IOException e) { 
      logger.error(e); 
     } 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Parent root = FXMLLoader.load(getClass().getResource("/welcome.fxml")); 
     Scene scene = new Scene(root); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    @Override 
    public void stop() throws Exception { 
     super.stop(); 

     // to avoid NullPointerException 
     if (Client != null && Client.getSocket() != null) { 
      Client.getSocket().close(); 
     } 
    } 
} 

クライアント:

public class Client { 

    private Socket socket; 
    public Client(String remoteHost, int port) throws UnknownHostException, IOException { 
     if (getSocket() == null) { 
      socket = new Socket(remoteHost, port); 
     } 
    } 

    public Client() throws UnknownHostException, IOException { 
     this(Constants.REMOTE_HOST, Constants.REMOTE_PORT); 
    } 

    public Socket getSocket() { 
     return socket; 
    } 
} 
+1

@ControlAltDel重複が間違っています。 'SocketException:SocketException:connection reset'と同じではありません。再オープン。 – EJP

答えて

1

あなたが正しいです。クライアントを終了する前に、クライアントソケットを適切に閉じる必要があります。そうしないと、オペレーティングシステムが接続をリセットするのではなく、接続をリセットすることがあります。 Androidの男ではないので、この閉鎖をどこに置くべきかアドバイスできません。

サーバーにも問題があります。読み取りループでEOFExceptionを捕らえて静かに壊す必要があります。現在のところ、ストリームの終わりを正確に処理しているわけではありません。catch (EOFException)でキャッチし、エラーとしてログに記録します。実際にはそうではありません。

関連する問題