java.net.BindException:地址已在使用中(绑定失败)

问题描述 投票:0回答:1

我正在使用 MVC 架构在 javafx 中编写电子邮件应用程序。 服务器的启动方法是这样的

    @Override
    public void run() {
        try {
            serverSocket = new ServerSocket(PORT);
            controller.logEvent(Protocol.SERVER_STARTED, true, null, null);
            loadAccounts();
            while (isRunning.get()) {
                try {
                    Socket socket = serverSocket.accept();
                    if (isRunning.get()) {
                        connectedClients.add(socket);
                        Thread thread = new Thread(() -> {
                            handleClient(socket);
                            connectedClients.remove(socket);
                        });
                        thread.start();
                    } else {
                        socket.close();
                    }
                } catch (SocketException e) {
                    if (!isRunning.get()) {
                        break;
                    } else {
                        throw e;
                    }
                }
            }
        } catch (IOException e) {
            controller.logEvent(Protocol.SERVER_STARTED, false, null, null);
            e.printStackTrace();
        }
    }

而停止服务器的是这样的:

    public void stopServer() {
        isRunning.set(false);
        try {
            if (serverSocket != null) {
                serverSocket.setReuseAddress(true);
                serverSocket.close();
                controller.logEvent(Protocol.SERVER_STOPPED, true, null, null);
                for (Socket socket : connectedClients) {
                    socket.close();
                }
                connectedClients.clear();
            }
        } catch (IOException e) {
            controller.logEvent(Protocol.SERVER_STOPPED, false, null, null);
            e.printStackTrace();
        }
    }

Il mio problema risiede nella ripartenza del server。 Quando provo a farlo ripartire, mi da' questi errori:

java.net.BindException: Address already in use (Bind failed)
    at java.base/java.net.PlainSocketImpl.socketBind(Native Method)
    at java.base/java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:452)
    at java.base/java.net.ServerSocket.bind(ServerSocket.java:395)
    at java.base/java.net.ServerSocket.<init>(ServerSocket.java:257)
    at java.base/java.net.ServerSocket.<init>(ServerSocket.java:149)
    at MailServer.run(MailServer.java:71)
    at java.base/java.lang.Thread.run(Thread.java:829)

我重启服务器的方法是这样的:

    public void startServer() {
        try {
            if (serverSocket != null && !serverSocket.isClosed()) {
                serverSocket.setReuseAddress(true);
                serverSocket.close();
            }
            isRunning.set(true);
            serverSocket = new ServerSocket(PORT);
            Thread thread = new Thread(this);
            thread.start();
            controller.logEvent(Protocol.SERVER_STARTED, true, null, null);
        } catch (IOException e) {
            controller.logEvent(Protocol.SERVER_STARTED, false, null, null);
        }
    }

你有什么建议可以解决我的问题吗?我发现问题是服务器停止时端口没有释放,但我不知道如何解决它。

java javafx server client port
1个回答
0
投票

REUSEADDR 不是关于在关闭时“释放”地址,而是关于允许绑定到正在使用的地址。地址(端口)will 在套接字关闭后被某些人“使用”,这就是协议必须工作的方式。

当您最初在“运行”方法中绑定套接字时,您创建它时没有使用 REUSEADDR,这就是您的异常来源。

我不太熟悉 Java 服务器套接字(但有 C 套接字的经验),但是文档说你想做的是

创建一个未绑定的套接字(使用无参数构造函数)
设置重用地址
将套接字绑定到接口和端口

按照这个顺序。不要理会关闭时间的事情,但每次创建新的 ServerSocket 时都这样做。

© www.soinside.com 2019 - 2024. All rights reserved.