【问题标题】:Checking if server is online from Java code从 Java 代码检查服务器是否在线
【发布时间】:2016-12-08 14:00:35
【问题描述】:

我想检查服务器应用程序是否可用。服务器启动后,我想停止检查,直到服务器更改状态。如何用我的代码做到这一点:

 private static final String SERVER_ADDRESS = "192.144.10.10";
    private static final int TCP_SERVER_PORT = 8890;
    private static boolean connected = false;
    static Socket s;

    public static void main(String[] args) {

    Timer timer = new Timer();
    timer.schedule(task, 01, 5001); }  

static TimerTask task = new TimerTask() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            if (connected == false)
            {
            System.out.println(hostAvailabilityCheck());
            }
        }
    };

    public static boolean hostAvailabilityCheck()
    { 

        boolean available = true; 
        try {               
            if (connected == false)
            { (s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)).close();    
            }               
            } 
        catch (UnknownHostException e) 
            { // unknown host 
            available = false;
            s = null;
            } 
        catch (IOException e) { // io exception, service probably not running 
            available = false;
            s = null;
            } 
        catch (NullPointerException e) {
            available = false;
            s=null;
        }


        return available;   
    } 

有没有更好的方法来解决这个问题?

【问题讨论】:

  • 静态字段connected 似乎没什么用,因为你永远不会改变它
  • 好吧,这将检查主机/端口对是否可用,但它不会检查任何功能......可能是后面的服务软件是 fubar 并且总是返回 500 用于 HTTP,因为实例
  • 这可以帮助你stackoverflow.com/questions/9552743/… 你的 URL(URL_TO_APPLICATION) 可以是 SERVER_ADDRESS + TCP_SERVER_PORT 也可以看到这个coderanch.com/t/205709/sockets/java/check-server
  • 您在检查什么,物理服务器的可用性,或在其上运行的应用程序,如 Tomcat?

标签: java sockets


【解决方案1】:

check 方法可以重写如下(Java 7 及更高版本):

public static boolean hostAvailabilityCheck() { 
    try (Socket s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)) {
        return true;
    } catch (IOException ex) {
        /* ignore */
    }
    return false;
}

除了简化异常处理之外,这还消除了令人讨厌的Socket 泄漏。 (如果您担心执行此检查所花费的时间,请在尝试连接之前设置连接超时:请参阅Setting a timeout for socket operations

但是这种方法的问题是多方面的:

  • 它只测试 something 正在监听连接。如果您的服务位于代理后面...或由inetd 服务之类的东西管理...那么接受的连接并不意味着您的服务实际上正在运行。

  • 这将导致您的服务“看到”在未发送请求的情况下关闭的连接。所以你最好编写你的服务来“优雅地”处理这个问题。

  • 重复执行此操作会增加网络和服务器负载。

  • 如果您因为不希望测试“冻结”而设置了一个较短的超时时间,那么您就有可能将其设置得太短,并在没有超时时判断主机已关闭。


服务器启动后我想停止检查,直到服务器改变状态

这几乎是不可能的。原因是您将无法在不检查的情况下判断服务器是否已“更改状态”。或者至少,如果不实施详细的状态通知服务,服务器调用客户端告诉它正在更改状态,您将无法做到这一点。 (如果“更改状态”包括“死亡”或“丢失的网络连接”,那么您将无法使 通知可靠......如果有的话。)

【讨论】:

    【解决方案2】:
    public static boolean hostAvailabilityCheck() { 
        try (Socket s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT)) {
            return true;
        } catch (IOException ex) {
            /* ignore */
        }
        return false;
    }
    

    工作,但问题是当您通过 WI-FI 打开手机时,它会“急停”并且没有任何动作。思考...=)

    下一个代码将通过 WI-FI 工作...如果您增加连接时间 -

    public static boolean isOnline() {
        boolean b = true;
        try{
            InetSocketAddress sa = new InetSocketAddress("SERVER_IP_ADDRESS", PORT);
            Socket ss = new Socket();
            ss.connect(sa, 1);            --> change from 1 to 500 (for example)
            ss.close();
        }catch(Exception e) {
            b = false;
        }
        return b;
    }
    

    【讨论】:

      【解决方案3】:

      首先检查服务器是否正在运行并且服务器是否接受连接。

         public static boolean hostAvailabilityCheck()
      { 
          s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT);
          boolean available = true; 
          try {               
              if (s.isConnected())
              { s.close();    
              }               
              } 
          catch (UnknownHostException e) 
              { // unknown host 
              available = false;
              s = null;
              } 
          catch (IOException e) { // io exception, service probably not running 
              available = false;
              s = null;
              } 
          catch (NullPointerException e) {
              available = false;
              s=null;
          }
      
      
          return available;   
      } 
      

      【讨论】:

      • 三个catch块上的代码都是一样的;它可以合并为一个(在这种情况下可能应该是)。
      • 最好假设服务器不可用 (boolean available = false),然后当且仅当您能够访问它时才将其设置为 true。这样,如果出现异常或出现故障,我们就不会根据现在不正确的布尔值继续连接。
      • @AaronDigulla 我不确定他是否在使用 J7
      • 那么你应该使用线程来检查连接。由于这是 tcp,您应该使用线程发送连接请求并经常获取响应。
      • 在您刚刚连接后测试s.isConnected() 完全没有意义。如果没有连接,构造函数会抛出异常。
      【解决方案4】:

      我在我的 ServerUtil 中使用了这种方法。

          public static boolean isOnline() {
          boolean b = true;
          try{
              InetSocketAddress sa = new InetSocketAddress("SERVER_IP_ADDRESS", PORT);
              Socket ss = new Socket();
              ss.connect(sa, 1);
              ss.close();
          }catch(Exception e) {
              b = false;
          }
          return b;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-19
        • 2011-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-22
        • 2012-11-05
        • 2017-09-13
        相关资源
        最近更新 更多