线程服务器卡在accept()AKA如何通过客户端输入关闭MulThreaded服务器?

时间:2016-09-28 20:13:04

标签: java sockets server client

由于我现在已经坚持了一个星期而仍然没有把它固定下来,我试着尽可能地表达我想要的东西。

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

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

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

下面你看到我的Server类的实现,其他两个涉及的类是Client(他所做的就是连接到Socket)和RequestHandler(这个类处理输入并写入它)。 我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();
            }
        }
    }

}

1 个答案:

答案 0 :(得分:1)

如果您将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 ...  
     }
}

这种模式实际上并不是那么好,但对于这里来说会更好。希望这能让你有一个良好的开端。