线程服务器卡在accept()AKA上如何通过客户端输入关闭MulThreaded服务器? [英] Threaded Server stuck on accept() AKA How to shutdown a MulThreaded Server via client input?

查看:81
本文介绍了线程服务器卡在accept()AKA上如何通过客户端输入关闭MulThreaded服务器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于我已经坚持了一个星期,但仍然没有解决问题,所以我尝试尽可能清晰地表达我想要的内容.

Since I am stuck for this for a week now and still haven't firgured it out I try to express what I want as cleary as possible.

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

I have a Server which can handle Multiple Clients and communicates with them. Whenever a client connects, the server passes the Client's request to my class RequestHandler, in which the clients commands are being processed. If one of the clients says "SHUTDOWN", the server is supposed to cut them loose and shut down. It doesn't work. If only one client connects to the server, the server seems to be stuck in the accept() call and I do not know how to fix this.

已经有一个回复,但是请不要注意到它,因为它涉及的主题已经过时了

THERE is already one response, but please do not take note of it, it was on a different topic which is outdated

我有两种方法,但两种方法似乎都无效. 1)如果客户端写"SHUTDOWN",则shutdownFlag设置为true(以希望退出while循环) 2)如果客户端写"SHUTDOWN",则在服务器上调用静态方法shutdown(),应将其关闭

I have two approaches and both don't seem to work. 1)If the client writes "SHUTDOWN", the shutdownFlag is set to true (in hope to exit the while loop) 2)If the client writes "SHUTDOWN", the static method shutdown() is called on the Server, which should shut him down

在下面看到我的Server类的实现,所涉及的其他两个类是Client(他所做的只是连接到Socket)和RequestHandler(该类处理Input并将其写入). 我98%确信问题出在Server类之内.

Below you see the implementation of my Server class, the other two classes involved are Client(all he does is connect to the Socket) and RequestHandler (this class processes the Input and writes it) . I am 98% sure the problem lies within the Server class.

下面是服务器的甚至更短的版本,其中仅包含没有控制台输出的方法,这可能有助于您在复制代码的情况下理解它

Below this is an even shorter version of the Server with just the methods without any Console outputs which might help understanding it in case you want to copy the code

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),则只需执行main内.这样,您就可以在run方法中使用实例(this). 像这样:

If you move the code in main into an instance method on Server (we'll say run here) you can just do new Server().run() inside main. That way you have an instance (this) to work with inside your run method. Something like this:

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 ...  
     }
}

这种模式实际上并不好,但是更好的方法对于这里来说太长了.希望这可以让您有个良好的开端.

This pattern isn't actually that great but better would be too long for here. Hopefully this gets you off to a good start.

这篇关于线程服务器卡在accept()AKA上如何通过客户端输入关闭MulThreaded服务器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆