Java快速检查网络连接

时间:2011-08-09 16:08:22

标签: java networking java-5

我的问题相当简单。如果网络连接丢失,我的程序需要立即通知。我使用的是Java 5,因此我无法使用NetworkInterface的非常方便的功能。

目前,我有两种不同的方法来检查网络连接:
(try..catches删除)

方法一:

URL url = new URL("http://www.google.com");
HttpURLConnection urlConnect = (HttpURLConnection) url.openConnection();
// trying to retrieve data from the source. If offline, this line will fail:
Object objData = urlConnect.getContent();
return true;

方法2:

Socket socket = new Socket("www.google.com", 80);
netAccess = socket.isConnected();
socket.close();
return netAccess;

但是,这两种方法都会阻塞,直到达到超时才返回false。我需要一个立即返回的方法,但与Java 5兼容。

谢谢!

编辑: 我忘了提到我的程序依赖于IP地址,而不是DNS名称。因此在解析主机时检查错误......

第二次编辑:

使用NetworkInterface找出最终解决方案:

Enumeration<NetworkInterface> eni = NetworkInterface.getNetworkInterfaces();
        while(eni.hasMoreElements()) {
            Enumeration<InetAddress> eia = eni.nextElement().getInetAddresses();
            while(eia.hasMoreElements()) {
                InetAddress ia = eia.nextElement();
                if (!ia.isAnyLocalAddress() && !ia.isLoopbackAddress() && !ia.isSiteLocalAddress()) {
                    if (!ia.getHostName().equals(ia.getHostAddress()))
                        return true;
                }
            }
        }

4 个答案:

答案 0 :(得分:10)

来自JGuru

  

从Java 5开始,中有一个isReachable()方法   InetAddress类。您可以指定超时或   要使用的NetworkInterface。有关底层的更多信息   ping使用的Internet控制消息协议(ICMP),请参阅RFC 792   (http://www.faqs.org/rfcs/rfc792.html)。

Java2s的用法

  int timeout = 2000;
  InetAddress[] addresses = InetAddress.getAllByName("www.google.com");
  for (InetAddress address : addresses) {
    if (address.isReachable(timeout))
      System.out.printf("%s is reachable%n", address);
    else
      System.out.printf("%s could not be contacted%n", address);
  }

如果要避免阻塞,请在java.nio包中使用Java NIO(非阻塞IO)

String host = ...; 
InetSocketAddress socketAddress = new InetSocketAddress(host, 80); 
channel = SocketChannel.open(); 
channel.configureBlocking(false); 
channel.connect(socketAddress);

答案 1 :(得分:3)

  

如果是网络连接,我的程序需要立即通知   丢失。

运气不好。您无法通过TCP / IP立即获得通知。它充满了缓冲,重试和超时,因此它不会立即执行任何,并且TCP设计中没有任何与“拨号音”相对应的内容,也没有任何API。检测丢失连接的唯一方法是尝试对其进行I / O操作。

  

我正在使用Java 5,所以我无法使用非常方便的功能   的NetworkInterface。

他们也不会帮助你。所有他们都可以告诉你的是网卡是上升还是下降,与你与更广阔世界的联系状态无关。

URL url = new URL("http://www.google.com");
HttpURLConnection urlConnect = (HttpURLConnection) url.openConnection();
// trying to retrieve data from the source. If offline, this line will fail:
Object objData = urlConnect.getContent();
return true;

如果您处于离线状态,则会因DNS失败而超时。

Socket socket = new Socket("www.google.com", 80);
netAccess = socket.isConnected();
socket.close();
return netAccess;

同上。但是,即使它没有,socket.isConnected()也总是返回true。那些API,如isConnected(),isBound(),isClosed(),只告诉你套接字做了什么。他们没有告诉你关于状态的任何信息连接。他们不能,因为我给出了上述原因。

如果发生异常,您忘记关闭套接字,因此您有资源泄漏。

  

我需要一种能立即返回的方法。

由于给出的理由不可能。你需要重新设计这个功能不存在的实现。

答案 2 :(得分:2)

您需要先创建名为interface的{​​{1}},例如

NetworkListener

接下来,创建一个类并将其称为public interface NetworkListener { public void sendNetworkStatus(String status); } ,例如

NetworkStatusThread

然后在您的实例化public class NetworkStatusThread implements Runnable { List listenerList = new Vector(); @SuppressWarnings("unchecked") public synchronized void addNetworkListener(NetworkListener nl) { listenerList.add(nl); } public synchronized void removeNetworkListener(NetworkListener nl) { listenerList.remove(nl); } private synchronized void sendNetworkStatus(String status) { // send it to subscribers @SuppressWarnings("rawtypes") ListIterator iterator = listenerList.listIterator(); while (iterator.hasNext()) { NetworkListener rl = (NetworkListener)iterator.next(); rl.sendNetworkStatus(status); } } public void run() { while (true) { System.out.println("Getting resource status"); try { Thread.sleep(2000); System.out.println("Sending resource status to registered listeners"); this.sendResourceStatus("OK"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 的类中,执行以下操作:

Thread

此外,在该课程中,您需要NetworkStatusThread netStatus = new NetworkStatusThread(); netStatus.addNetworkListener(this); Thread t = new Thread(netStatus); t.Start(); implement,才能获得回调。

在上面的NetworkListener方法中,您可以通过@Ali实现代码,但是可以通过我的状态:

run()

答案 3 :(得分:0)

您是否尝试过发布DNS解析?

您可以尝试:

public static InetAddress[] getAllByName(String host)

但我不确定这是否也需要超时..