使用InetAddress指定端口的JAVA相关问题

9

我正在使用 InetAddress 来确定我的服务器是否在线。

如果服务器离线,它将重新启动服务器。

此过程每 5 分钟循环一次,以再次检查服务器是否在线。

它工作得很好,但现在我需要弄清楚如何指定在检查服务器状态时使用端口 43594 而不是默认的端口 80。

谢谢!这是我的代码:


```java InetAddress address = InetAddress.getByName("example.com"); if (!address.isReachable(5000)) { // restart server } ```
请注意,以上代码中没有指定端口。
import java.net.InetAddress;
public class Test extends Thread {
    public static void main(String args[]) {
        try {
            while (true) {
                try
                {
                    InetAddress address = InetAddress.getByName("cloudnine1999.no-ip.org");
                    boolean reachable = address.isReachable(10000);
                    if(reachable){
                        System.out.println("Online");
                    }
                    else{
                        System.out.println("Offline: Restarting Server...");
                        Runtime.getRuntime().exec("cmd /c start start.bat");
                    }
                }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
                Thread.sleep(5 * 60 * 1000);
            }
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

编辑:

好的,我采纳了某人的建议,把代码改成了这样。但是,现在当我取消注释这行代码时.. Runtime.getRuntime().exec("cmd /c start start.bat");

我会收到这个错误..

error: unreported exception IOException; must be caught or declared to be thrown

这是我的当前代码:

import java.net.*;
import java.io.*;
public class Test extends Thread {
    public static void main(String args[]) {
        try {
            while (true) {
                SocketAddress sockaddr = new InetSocketAddress("cloudnine1999.no-ip.org", 43594);
                Socket socket = new Socket();
                boolean online = true;
                try {
                    socket.connect(sockaddr, 10000);
                }
                catch (IOException IOException) {
                    online = false;
        }
                if(!online){
            System.out.println("OFFLINE: Restarting Server..");
            //Runtime.getRuntime().exec("cmd /c start start.bat");
        }
                if(online){
                    System.out.println("ONLINE");
                }
                Thread.sleep(1 * 10000);
            }
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

你尝试过修改主机参数以包括端口吗?cloudnine1999.no-ip.org:43594 - FThompson
Javadoc中写道:“典型的实现将使用ICMP ECHO REQUEST(如果可以获得特权),否则它将尝试在目标主机的端口7(Echo)上建立TCP连接。” - 你确定你正在使用的实现实际上是在端口80上进行测试连接吗? - fvu
@Vulcan 谢谢,但我已经尝试过了。 - Cloudnine1999
@fvu 我实际上正在尝试测试端口43594,而不是80,我以为它在测试端口80,我没有意识到默认情况下它会测试端口7。但这只是细节问题,我需要它从检查的任何端口更改为端口43594。 - Cloudnine1999
1个回答

12

正如我在评论中提到的那样,根据Javadoc,isReachable的实现方式不允许您控制所选端口。 实际上,如果系统特权允许这样做,它将只会对机器进行ping测试(ICMP请求)。

手动执行此操作(即使用套接字)肯定可以工作,并且并不真正更复杂和/或更长:

SocketAddress sockaddr = new InetSocketAddress("cloudnine1999.no-ip.org", 43594);
// Create your socket
Socket socket = new Socket();
boolean online = true;
// Connect with 10 s timeout
try {
    socket.connect(sockaddr, 10000);
} catch (SocketTimeoutException stex) {
    // treating timeout errors separately from other io exceptions
    // may make sense
    online=false;
} catch (IOException iOException) {
    online = false;    
} finally {
    // As the close() operation can also throw an IOException
    // it must caught here
    try {
        socket.close();
    } catch (IOException ex) {
        // feel free to do something moderately useful here, eg log the event
    }

}
// Now, in your initial version all kinds of exceptions were swallowed by
// that "catch (Exception e)".  You also need to handle the IOException
// exec() could throw:
if(!online){
    System.out.println("OFFLINE: Restarting Server..");
    try {
        Runtime.getRuntime().exec("cmd /c start start.bat");
    } catch (IOException ex) {
         System.out.println("Restarting Server FAILED due to an exception " + ex.getMessage());
    }
}        

编辑:忘记处理 IOException,这也意味着服务器没有运行,已添加。

编辑2:添加了可以抛出close()的IOException的处理。

编辑3:为exec()添加异常处理。


哦,还有socket.close()必须被删除,它也会导致错误。 - Cloudnine1999
不,你不应该删除它,我修改了我的代码以展示如何在本地捕获它。在Java中,在close()操作中抛出异常并不是最有用的功能,但这就是现实。对于造成的混淆感到抱歉,我用于测试此类片段的小型测试程序已经有了throws IOException,这导致我错过了这个问题。 - fvu
还有一个例子,展示了如何捕获和处理exec抛出的异常。我认为程序现在几乎完成了,你觉得呢? :-) - fvu
几乎...SocketTimeoutException的catch块几乎无法触及。它已经被IOException的catch块处理了 :-) - harschware
@harschware 确实,发现得好 - 代码已经被纠正了。 - fvu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接