正确关闭ServerSocket的方法

时间:2016-12-17 16:41:54

标签: java sockets serversocket

我正在学习使用ServerSocket,并在方法serverSocket工作时尝试关闭accept()对象时出错。接下来,我找到了setSoTimeout()方法的解决方案。但我认为忽略异常不是最佳做法。 所以,这是我的两个班级:

服务器

public class Server {
    public static final int PORT = 8777;
    private ServerSocket serverSocket;
    private boolean serverRuns;

    Server() {
        try {
            serverSocket = new ServerSocket(PORT);
            serverRuns = true;

            (new Control(this)).start(); // Takes commands while working
            while (serverRuns) {
                try {
                    serverSocket.setSoTimeout(1000);
                    Socket clientSocket = serverSocket.accept();
                }
                catch (SocketTimeoutException e) {
                    // cap
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                serverSocket.close();
                System.out.println("Server stopped");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public void stopServer() {
        serverRuns = false;
    }
    public boolean isServerRuns() {
        return serverRuns;
    }
    public static void main(String[] Args) {
        Server s = new Server();
    }
}

上课控制

public class Control extends Thread {
    private Server activeServer;

    private Control() {}
    Control(Server activeServer) {
        this.activeServer = activeServer;
    }
    @Override
    public void run() {
        Scanner keyboard = new Scanner(System.in);

        while (activeServer.isServerRuns()) {
            String key = keyboard.nextLine().toLowerCase();

            switch (key) {
                case "close":
                    activeServer.stopServer();
                    break;
            }
        }
    }
}

终止ServerSocket工作是否正确(忽略异常并每秒检查一次serverRuns变量)?欢迎任何建议

2 个答案:

答案 0 :(得分:1)

您需要从另一个线程调用服务器,因为serverSocket.accept();将阻止

看看:Interrupt accept method and close the server

答案 1 :(得分:0)

扩展Xephi的答案:

  

您需要从另一个线程关闭服务器

好吧,不需要从另一个线程调用the ServerSocket.close(),但这当然是一种明智的方法。

  

那正是他已经在做的。 – user207421

不,不是。 OP正在做的是复位另一个线程中的serverRuns标志,并借助Server调用的套接字超时来定期检查主accept()中的该标志;我称那为丑陋。

采用推荐的方法,Server类似于:

    Server()
    {
        try
        {
            serverSocket = new ServerSocket(PORT);
            (new Control(this)).start(); // Takes commands while working
            while (true)
            {
                Socket clientSocket = serverSocket.accept();
                …
            }
        } catch (SocketException e) { System.out.println("Server stopped"); }
          catch (IOException e)     { e.printStackTrace(); }
    }

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

Control循环可以简化为:

        while (true)
        {
            String key = keyboard.nextLine().toLowerCase();
            switch (key)
            {
                case "close":
                    activeServer.stopServer();
                    return;
            }
        }