【问题标题】:How to correctly stop serverSocket.accept()如何正确停止 serverSocket.accept()
【发布时间】:2018-01-22 23:19:54
【问题描述】:

我正在编写一个简单的客户端/服务器聊天程序。服务器以这种方式处理多个客户端:

public void start(int port)
{
    (new Thread(new Runnable()
    {
        @Override
        public void run() {
            try{
                serverSocket = new ServerSocket(port);
                SocketHandler handler;
                while(true)
                {
                    handler = new SocketHandler(serverSocket.accept());
                    handlersList.add(handler);
                    (new Thread(new SocketHandler(socket))).start();
                }
            }catch(IOException e)
            {
                for(SocketHandler handler:handlersList)
                    handler.close();
            }
        }
    })).start();
}

public void stop() throws IOException
{
    serverSocket.close();
}

基本上 start() 实例化 ServerSocket 并无限期地等待客户端连接。每当用户想要关闭服务器时,服务器 Socket 就会关闭,这会导致 accept() 失败并抛出异常。然后 catch(){} 关闭创建的各种套接字。我的问题是:

  1. 是否必须关闭通过 serverSocket.accept() 创建的每个套接字?

  2. 这是停止此类服务器的正确方法吗? while(true) + 在非异常情况下使用异常对我来说感觉很不对劲。有没有更好的办法?

  3. 我可以使用 ExecutorService,然后在其上调用 shutdownNow 吗? shutdownNow 能否停止 accept() 调用?因为 api 文档声明它不能保证成功。

请随时指出我所做的任何错误/糟糕的设计选择。类型

【问题讨论】:

  • 仅仅因为accept() 出现错误而关闭所有处理程序是不正确的。当他们的客户端断开连接或通过读取超时时,您应该让他们以自己的方式完成。

标签: java sockets java.util.concurrent


【解决方案1】:

您可以使用close() 方法手动关闭连接(客户端/服务器端),也可以设置timeout

设置阻塞 Socket 操作的超时时间:

ServerSocket.accept();
SocketInputStream.read();
DatagramSocket.receive();

该选项必须在进入阻塞操作之前设置 影响。如果超时到期并且操作将继续 块,引发 java.io.InterruptedIOException。套接字不是 在这种情况下关闭。


这是停止此类服务器的正确方法吗?

正如你所说,它是一个服务器,这意味着你不需要停止它,但在特殊情况下。


正如你所说的shutdownNow() API 说:

除了尽力停止处理之外,没有任何保证 积极执行任务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 2013-05-29
    相关资源
    最近更新 更多