java - 是什么导致了java.net.SocketException : Connection reset after closing client?

标签 java sockets javafx serversocket socketexception

我正在为学校编写一个服务器/客户端应用程序。

每次关闭客户端时,服务器都会抛出“java.net.SocketException:连接重置”。我想,我必须在关闭 JavaFX 窗口之前关闭客户端中的套接字,但是在哪里?或者你觉得怎么样?

我见过类似的问题,但我不知道如何在我的程序中正确实现它。

异常(exception):

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

我的程序:

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

我的服务器:

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();
            }
        }

    }

服务器处理程序:

@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);
        }
    }

主客户端:

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;
    }
}

最佳答案

你是对的。在退出客户端之前,您必须正确关闭客户端套接字。否则操作系统可能会重置连接而不是关闭它。作为一个 Android 人员,我无法建议您应该将这个闭包放置在哪里。

你的服务器也有问题。它需要在读取循环中捕获EOFException并静默中断。目前,您没有正确处理流结束:您将通过 catch (EOFException ) 捕获它并将其记录为错误,但事实并非如此。

关于java - 是什么导致了java.net.SocketException : Connection reset after closing client?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38151578/

相关文章:

java - 环境配置管理?

java - 在 JTable 单元格上编辑没有效果

c - C 中的写入和读取,套接字 AF_UNIX

Java:套接字未获取输入

根据场景属性的Javafx Mediaview设置

java - 有没有更好的方法来检查字符串中是否有数字?

java - 在没有 getValueAt() 并发症的情况下修剪 AbstractTableModel

java - Android HTTP 连接

java - JavaFX 启动时的奇怪连接

javafx:如何创建一个显示包含文件路径的工具提示的 TreeItem 并在双击时加载文件路径?