从Java代码检查服务器是否在线

Jos*_*sef 20 java sockets

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

 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;   
    } 
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*n C 28

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;
}
Run Code Online (Sandbox Code Playgroud)

除了简化异常处理外,还可以消除烦人的Socket泄漏.(如果您担心执行此检查所花费的时间,请在尝试连接之前设置连接超时:请参阅设置套接字操作的超时)

但这种方法的问题很多:

  • 它只测试某些东西正在监听连接.如果您的服务在代理服务器后面......或者由inetd服务等类似的服务管理...那么接受的连接并不意味着您的服务实际上正在运行.

  • 这将导致您的服务"看到"关闭而不发送请求的连接.因此,您最好对您的服务进行编码,以"优雅地"处理此问题.

  • 重复这样做会增加网络和服务器负载.

  • 如果您因为不希望测试"冻结"而设置短暂超时,那么您可能会将其设置得太短并且判断主机在没有时关闭.


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

这几乎是不可能的.原因是如果不进行检查,您将无法判断服务器是否已"更改状态".或者至少,如果没有实现精心设置的状态通知服务,您将无法执行此操作,其中服务器调用客户端以告知它正在更改状态.(如果"更改状态"包括"死亡"或"丢失网络连接",那么您将无法使通知可靠...如果有的话.)


小智 6

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

工作正常,但问题是当你通过 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;
}
Run Code Online (Sandbox Code Playgroud)


Mur*_*ali 2

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

   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;   
} 
Run Code Online (Sandbox Code Playgroud)

  • 最好假设服务器不可用(“boolean available = false”),然后当且仅当您能够访问它时将其设置为 true。这样,如果出现异常或出现故障,我们就不会继续基于现在不正确的布尔值进行连接。 (7认同)
  • 在刚刚连接后测试“s.isConnected()”线路是完全没有意义的。如果没有连接,构造函数就会抛出异常。 (3认同)
  • 所有三个“catch”块上的代码都是相同的;它可以合并为一个(在这种情况下可能应该如此)。 (2认同)