21

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

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

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

4

4 回答 4

34

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泄漏。(如果您担心执行此检查所花费的时间,请在尝试连接之前设置连接超时:请参阅设置套接字操作超时

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

  • 它只测试某些东西正在监听连接。如果您的服务位于代理之后……或者由inetd服务之类的东西管理……那么接受的连接并不意味着您的服务实际上正在工作。

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

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

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


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

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

于 2013-06-17T14:21:41.423 回答
6
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;
}
于 2016-12-08T06:00:35.103 回答
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;   
} 
于 2013-06-17T12:40:44.020 回答
-1

我将这种方法用于我的 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;
}
于 2015-11-23T18:47:34.073 回答