Java应用程序即使 "CLOSE ON EXIT"也无法关闭,TCP服务器

标签 java sockets tcp server

我只想制作一个服务器应用程序,它获取字符串并将它们放入 JTextArea 中。即使没有显示任何错误,我也收到两个错误。

  1. 尽管我使用了这个语句,但窗口无法关闭:

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  2. 如果客户端连接到服务器,整个窗口将变黑。可能是什么错误?代码如下:

客户:

public Main() {
    super("Main");
    setIconImage(Toolkit.getDefaultToolkit().getImage(Main.class.getResource("/images/ic.png")));

    panelFields = new JPanel();
    panelFields.setLayout(new BoxLayout(panelFields,BoxLayout.X_AXIS));
    panelFields2 = new JPanel();
    panelFields2.setLayout(new BoxLayout(panelFields2,BoxLayout.X_AXIS));

    scrollPane = new JScrollPane();
    panelFields.add(scrollPane);

    getContentPane().add(panelFields);
    getContentPane().add(panelFields2);
    getContentPane().setLayout(new BoxLayout(getContentPane(),BoxLayout.Y_AXIS));
    setSize(326, 264);
    setVisible(true);

    messagesArea = new JTextArea();
    scrollPane.setViewportView(messagesArea);
    messagesArea.setColumns(30);
    messagesArea.setRows(10);
    messagesArea.setEditable(false);

    startServer = new JButton("Start");
    startServer.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            socketConnection();
            startServer.setEnabled(false);
        }
    });

    panelFields.add(startServer);
}

和服务器连接:

private void socketConnection() {
    try {
        serverSocket = new ServerSocket(9090);
        System.out.println("Listening: " + serverSocket.getLocalPort());
    } catch (IOException e) {
        e.printStackTrace();
    }

    while (true) {
        try {
            socket = serverSocket.accept();
            dataInputStream = new DataInputStream(socket.getInputStream());
            System.out.println("ip: " + socket.getInetAddress());
            System.out.println("message: " + dataInputStream.readUTF());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            if (dataInputStream != null) {
                try {
                    dataInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

也许你可以告诉我,如何解决这些问题,以及如何让服务器在客户端断开连接时不会关闭套接字。我想稍后重新连接...

最佳答案

您需要在自己的线程中启动套接字监听器,并且需要添加一个关闭该线程的窗口关闭监听器。

例如:

private ServerSocket serverSocket = null;
private boolean done = false;

private void startServer() {
    Thread t = new Thread(new Runnable() {
        public void Run() {
            socketConnection();
        });
    }
    t.start();
}

private void socketConnection() {
    try {
        serverSocket = new ServerSocket(9090);
        System.out.println("Listening: " + serverSocket.getLocalPort());

        while (!done) {
            try {
                final Socket socket = serverSocket.accept();
                Thread t = new Thread(new Runnable() {
                    public void Run() {
                        handle(socket);
                    }
                });
                t.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void handle(Socket socket) {
    if (socket == null) return;
    try {
        dataInputStream = new DataInputStream(socket.getInputStream());
        System.out.println("ip: " + socket.getInetAddress());
        System.out.println("message: " + dataInputStream.readUTF());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (dataInputStream != null) {
            try {
                dataInputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        try {
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


public void windowClosing(WindowEvent e) { 
    done = true; 
    socketServer.close(); 
} 

你的按钮点击监听器应该调用startServer(),然后你的窗口关闭函数将设置done = true并调用socketServer.close()。

现在您有一个用于 UI 的线程、一个用于套接字服务器的线程以及一个用于与服务器的每个连接的线程。

关于Java应用程序即使 "CLOSE ON EXIT"也无法关闭,TCP服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35094602/

相关文章:

java - JavaFx 和 @FXML 中的访问修饰符

java - Socket如何相互发送数据?

java - Netty IdleStateEvent 不会在服务器上引发 READER_IDLE

c# - 如果未检测到换行符,则服务器的套接字阻塞,但未检测到客户端的套接字

java - 尝试从套接字读取时连接重置

java - 带定制适配器的 NPE

JavaFX SceneBuilder ImageView 不工作

java - 如何sqlite + listview + onListItemClick启动新的Activity?光标读取错误

java - 基本 Netty 演示无法同时处理 TCP 和 UDP 套接字

c# - 创建没有 ip 地址的套接字连接(TCP 或 UDP)