Java Quickly check for network connection

前端 未结 4 1899
暗喜
暗喜 2021-02-20 08:14

My issue is fairly straightforward. My program requires immediate notification if a network connection is lost. I\'m using Java 5, so I\'m unable to use the very handy feature

相关标签:
4条回答
  • 2021-02-20 08:33

    You need to first create an interface called NetworkListener, for example

    public interface NetworkListener {
        public void sendNetworkStatus(String status);
    }
    

    Next, create a class and call it NetworkStatusThread, for example

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

    Then in your class that instantiates the Thread, do this:

    NetworkStatusThread netStatus = new NetworkStatusThread();
    netStatus.addNetworkListener(this);
    Thread t = new Thread(netStatus);
    t.Start();
    

    Also, in that class, you need to implement the NetworkListener, in order to get the callbacks.

    In your run() method above, you can implement the code by @Ali, but pass my status:

      int timeout = 2000;
      InetAddress[] addresses = InetAddress.getAllByName("www.google.com");
      for (InetAddress address : addresses) {
        if (address.isReachable(timeout))
           this.sendResourceStatus("OK");
        else
           this.sendResourceStatus("BAD");
      }
    
    0 讨论(0)
  • 2021-02-20 08:35

    Did you try by issuing a DNS resolve?

    You can try with:

    public static InetAddress[] getAllByName(String host)
    

    but I'm unsure if this will require the timeout too..

    0 讨论(0)
  • 2021-02-20 08:49

    From JGuru

    Starting with Java 5, there is an isReachable() method in the InetAddress class. You can specify either a timeout or the NetworkInterface to use. For more information on the underlying Internet Control Message Protocol (ICMP) used by ping, see RFC 792 (http://www.faqs.org/rfcs/rfc792.html).

    Usage from 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);
      }
    

    If you want to avoid blocking use Java NIO (Non-blocking IO) in the java.nio package

    String host = ...; 
    InetSocketAddress socketAddress = new InetSocketAddress(host, 80); 
    channel = SocketChannel.open(); 
    channel.configureBlocking(false); 
    channel.connect(socketAddress);
    
    0 讨论(0)
  • 2021-02-20 08:53

    My program requires immediate notification if a network connection is lost.

    Bad luck. You can't get an immediate notification with TCP/IP. It is full of buffering and retries and timeouts, so it doesn't do anything immediately, and TCP by design doesn't have anything corresponding to a 'dial tone', nor any API. The only way to detect a lost connection is to try to do I/O over it.

    I'm using Java 5, so I'm unable to use the very handy features of NetworkInterface.

    They won't help you either. All they can tell you is whether an NIC is up or down, nothing about the state of your connectedness to the wider world.

    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;
    

    That will timeout with a DNS failure if you're offline.

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

    Ditto. However even if it didn't, socket.isConnected() would always return true. Those APIs like isConnected(), isBound(), isClosed(), only tell you what you have done to the socket. They don't tell you anything about the state of the connection. They can't, for the reason I gave above.

    And you forgot to close the socket in the case of an exception, so you have a resource leak.

    I need a method that will return immediately.

    Impossible for the reasons given. You need to redesign around the realization that this function doesn't exist.

    0 讨论(0)
提交回复
热议问题