java - 线程服务器卡在accept()上又名如何通过客户端输入关闭多线程服务器?

标签 java sockets server client

由于我为此被困了一个星期,但仍然没有弄清楚,所以我尝试尽可能清楚地表达我想要的内容。

我有一个可以处理多个客户端并与它们通信的服务器。 每当客户端连接时,服务器都会将客户端的请求传递给我的 RequestHandler 类,其中正在处理客户端命令。 如果其中一个客户端说“SHUTDOWN”,服务器应该将它们松开并关闭。 这不起作用。 如果只有一个客户端连接到服务器,服务器似乎卡在accept()调用中,我不知道如何解决这个问题。

已经有一个回复,但请不要注意它,它是关于另一个已过时的主题

我有两种方法,但似乎都不起作用。 1)如果客户端写入“SHUTDOWN”,则shutdownFlag设置为true(希望退出while循环) 2)如果客户端写入“SHUTDOWN”,则在服务器上调用静态方法 shutdown(),这应该将其关闭

下面你可以看到我的Server类的实现,涉及的另外两个类是Client(他所做的只是连接到Socket)和RequestHandler(这个类处理Input并写入它)。 我 98% 确信问题出在 Server 类中。

下面是服务器的更短版本,只有方法,没有任何控制台输出,这可能有助于理解它,以防您想复制代码

public class Server {
    public static final int PORTNUMBER = 8540;
    public static final int MAX_CLIENTS = 3;
    public static boolean shutdownFlag = false;
    public static ExecutorService executor = null;
    public static ServerSocket serverSocket = null;

    public static void main(String[] args) {

        ExecutorService executor = null;
        try (ServerSocket serverSocket = new ServerSocket(PORTNUMBER);) {
            executor = Executors.newFixedThreadPool(MAX_CLIENTS);
            System.out.println("Waiting for clients");
            while (!shutdownFlag) {
                System.out.println("shutdown flag ist : " + shutdownFlag);          
                Socket clientSocket = serverSocket.accept();
                Runnable worker = new RequestHandler(clientSocket);
                executor.execute(worker);
                System.out.println("Hallo");

            }
            if (shutdownFlag) {
                System.out.println("Flag is on");               
                try {
                    executor.awaitTermination(10, TimeUnit.SECONDS);
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                 try {
                        //Stop accepting requests.
                        serverSocket.close();
                    } catch (IOException e) {
                        System.out.println("Error in server shutdown");
                        e.printStackTrace();
                    }
                serverSocket.close();
            }
            System.out.println("shutting down");
        } catch (IOException e) {
            System.out
                    .println("Exception caught when trying to listen on port "
                            + PORTNUMBER + " or listening for a connection");
            System.out.println(e.getMessage());
        } finally {
            if (executor != null) {
                executor.shutdown();
            }
        }
    }

    public static void shutdown(){
        if (shutdownFlag) {
            System.out.println("Flag is on");               
            try {
                executor.awaitTermination(10, TimeUnit.SECONDS);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
             try {
                    //Stop accepting requests.
                    serverSocket.close();
                } catch (IOException e) {
                    System.out.println("Error in server shutdown");
                    e.printStackTrace();
                }
            try {
                serverSocket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
<小时/>
public class Server {
    public static final int PORTNUMBER = 8540;
    public static final int MAX_CLIENTS = 3;
    public static boolean shutdownFlag = false;
    public static ExecutorService executor = null;
    public static ServerSocket serverSocket = null;

    public static void main(String[] args) {

        ExecutorService executor = null;
        try (ServerSocket serverSocket = new ServerSocket(PORTNUMBER);) {
            executor = Executors.newFixedThreadPool(MAX_CLIENTS);

            while (!shutdownFlag) {
                Socket clientSocket = serverSocket.accept();
                Runnable worker = new RequestHandler(clientSocket);
                executor.execute(worker);

            }
            if (shutdownFlag) {
                try {
                    executor.awaitTermination(10, TimeUnit.SECONDS);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                serverSocket.close();
            }
        } catch (IOException e) {
        } finally {
            if (executor != null) {
                executor.shutdown();
            }
        }
    }

    public static void shutdown() {
        if (shutdownFlag) {
            try {
                executor.awaitTermination(10, TimeUnit.SECONDS);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

最佳答案

如果您将代码移至 main进入 Server 上的实例方法(我们会在这里说 run )你可以这样做 new Server().run()里面main 。这样你就有一个实例( this )可以在你的 run 中使用。方法。 像这样的事情:

class Server {
     private boolean shutdownFlag = false; // This can't be static anymore.
     public static final Server SERVER = new Server();
     public static void main(String[] args) {
         SERVER.run();
     }
     private void run() {
         // Here goes everything that used to be inside main...
         // Now you have the Server.SERVER instance to use outside the class
         // to shut things down or whatever ...  
     }
}

这个模式实际上并不是那么好,但更好的是在这里太长了。希望这能让您有一个良好的开端。

关于java - 线程服务器卡在accept()上又名如何通过客户端输入关闭多线程服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39756825/

相关文章:

c - 测量 TCP 连接速度

sockets - Nodejs 流式传输

php - 避免 cURL 调用之间的网络问题

java - 从输入流中提取内容

java - 使用 json.simple 遍历嵌套 JSON 文件

java - 使用小程序向 unix 机器发送 Tab 键事件

java - 服务器启动时来自tomcat的通知回调

java - 图像IO异常

wcf - 如何为 WCF 编写基于套接字的自定义传输

Erlang 中的 Mysql