【问题标题】:How can I safely stop this Java server program?如何安全地停止这个 Java 服务器程序?
【发布时间】:2016-06-15 18:48:38
【问题描述】:

我想通过终端在我的 ubuntu 计算机上运行一个 java 服务器程序,但问题是一旦我启动程序我就无法停止它(程序正在终端中运行并等待客户端)。

这是我的代码:

import java.net.*; 
import java.io.*; 

public class EchoServer2 extends Thread {
    protected Socket clientSocket;

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;

        try {
            serverSocket = new ServerSocket(2000);
            System.out.println("Connection Socket Created");
            try {
                while (true) {
                    System.out.println("Waiting for Connection");
                    new EchoServer2(serverSocket.accept());
                }
            } catch (IOException e) {
                System.err.println("Accept failed.");
                System.exit(1);
            }
        } catch (IOException e) {
            System.err.println("Could not listen on port: 2000.");
            System.exit(1);
        } finally {
            try {
                serverSocket.close();
            } catch (IOException e) {
                System.err.println("Could not close port: 2000.");
                System.exit(1);
            }
        }
    }

    private EchoServer2(Socket clientSoc) {
        clientSocket = clientSoc;
        start();
    }

    public void run() {
        System.out.println("New Communication Thread Started");

        try {
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),
                    true);
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(clientSocket.getInputStream()));

            String inputLine;

            while ((inputLine = in.readLine()) != null) {
                System.out.println("Server: " + inputLine);
                out.println(inputLine);

                if (inputLine.equals("Bye."))
                    break;
            }

            out.close();
            in.close();
            clientSocket.close();
        } catch (IOException e) {
            System.err.println("Problem with Communication Server");
            System.exit(1);
        }
    }
}

我知道我可以终止该进程,但我不想强行停止该程序。我想知道:我怎样才能安全地停止程序?如何在我的代码中实现这一点?

【问题讨论】:

    标签: java sockets server


    【解决方案1】:

    让我们清楚一点,您在客户端接受时阻塞了主线程。干净地关闭程序将不是真正的方法。

    我的解决方案是运行一个单独的线程来完成接受工作。

    为了说明,这是我的代码:


    这是接受线程:

    private static Thread acception = new Thread("Acception Thread") {
    
        public void run() {
    
            try {
                while (true) {
                    System.out.println("Waiting for Connection");
                    new EchoServer2(serverSocket.accept());
                }
        ->  } catch (SocketException e) {
        ->      if(serverSocket.isClosed())
        ->          System.out.println("Connection Closed.");
        ->  }
            } catch (IOException e) {
                System.err.println("Accept failed.");
                System.exit(1);
            }
    
        }
    };
    

    这是修改后的main 方法:

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
    
    
        try {
            serverSocket = new ServerSocket(2000);
            System.out.println("Connection Socket Created");
    ->      acception.start();
        } catch (IOException e) {
            System.err.println("Could not listen on port: 2000.");
            System.exit(1);
        }
    
    
        //support to close, using the command line.
    
        Scanner scn = new Scanner(System.in);
        String s = scn.next();
    
        while(true) {
            if("quit".equals.(s)) {
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    System.err.println("Could not close port: 2000.");
                    System.exit(1);
                } finally {
                    break;
                }
            }
            s = scn.next();
        }
    }
    

    【讨论】:

      【解决方案2】:

      您可以点击Ctrl + C 键,它会向您的程序发送一个 SIGINT(中断)。如果您在程序关闭时没有要运行的特定逻辑,它可能会完成这项工作。

      如果您在程序关闭时需要运行一些逻辑,请检查this answer

      【讨论】:

      • 这当然会终止进程; OP 不想要的东西。
      • SIGINT(中断)与杀死进程的 SIGKILL 不同。否则,解决方法仍然是捕获信号并退出程序。
      【解决方案3】:

      检查这个链接http://www.oracle.com/technetwork/java/javase/signals-139944.html应该可以帮助你

      编辑: 解决方案 1:将此添加到您的 main 方法中

      Runtime.getRuntime().addShutdownHook(new Thread() {
         public void run() {
             System.out.println("Prepare to exit");
             //some cleaning up code...
         }
      });
      

      解决方案 2:添加另一个等待“退出”命令的线程,类似于:

          new Thread() {
              @Override
              public void run() {
                  System.out.println("Type exit to exit;-)");
                  Console c = System.console();
                  String msg = c.readLine();
                  if (msg.equals("exit")) {
                      //some cleaning up code...
                      System.exit(0);                 
                  }
              }
          }.start();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-17
        • 1970-01-01
        • 2020-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多