Přeskočit na hlavní obsah

Checking internet connection and connection to a particular server in Java


In AgroSense we need to know, if the computer is connected to the internet or not. And we don’t want to bother the user by throwing UnknownHostException or IOException also.

So we need two things:

  • Check the connection
  • Notify everybody interested, that the connectivity changed


When the first point is successfully implemented, the second one is easy – it is just a listener, so we will look only at the connectivity check problem.

Solution

For checking internet connectivity you need some host address. You will probably use the address, which you actually call, in our case it is www.openstreetmap.org.
In first step, we check, if there is some internet connection, this is done in a method isOnlineFastCheck:

    private boolean isOnlineFastCheck() {
        boolean check = false;
        try {
            InetAddress.getByName(hostName);
            check = true;
        } catch (UnknownHostException e) {
            //noop
        }
        return check;
    }

This method checks, if we have an internet connection, but doesn’t say anything about connection to our desired server.
Knowing, that we are online (exactly connected to a DNS server) we can do another check, this time for the server:

    private void doCheck() {
        boolean oldOnline = online;
        if (isOnlineFastCheck()) {
            try (Socket socket = new Socket(hostName, portNumber)) {
                online = (socket.getInputStream() != null);
            } catch (Throwable e) {
                online = false;
            }
        } else {
            online = false;
        }
        if (oldOnline != online) {
            propertyChangeSupport.firePropertyChange(PROPERTY_NAME, oldOnline, online);
        }
    }

Here we use the Socket class created for the server host name and port number and try to get the inputStream if stream is not null and no exception is thrown, we have connection to our server.
There is also used a propertyChangeSupport, so we can add a PropertyChangeListener to get notified whenever connectivity changes.
To have our goal complete we want to periodically call the check method. For this the Timer class is perfect:

Create TimerTask:

    private TimerTask createTimerTask() {
        return new TimerTask() {
            @Override
            public void run() {
                doCheck();
            }
        };
    }

Start and stop timer:

    public void start() {
        if (!started) {
            timer = new Timer("onlineChecker", true);
            timer.schedule(createTimerTask(), 0, checkPeriod);
            started = true;
        }
    }

    public void stop() {
        if (started) {
            timer.cancel();
            timer = null;
            started = false;
        }
    }

checkPeriod is set to 5000, so check happened every 5 seconds.
With all this code we can ask anytime, if our computer is online calling method:

    public boolean isOnline() {
        if (!isOnlineFastCheck()) {
            return false;
        } else {
            return online;
        }
    }

Conclusion

This solution is working fine, but still isn’t perfect. If you pull out your LAN cable in the middle of the check interval, you still can get UnknownHostException, IOException or something else. I wonder if JDK brings some complex solution for this problem one day.

Populární příspěvky z tohoto blogu

CPU killer in Java with JavaFX GUI client

Motivation Few weeks ago I was searching for a source of a bug in one of our applications. The QA team suspected that slow computer could be a reason for this. You know that - developers have Core i7 CPU with 8 GB RAM (at least some of us :-) ) and never realize, that users can have slow machine, which reacts differently . And for that tiny moment you would need slow computer, just to see how it works and whether you can break it. But how to achieve this? The QA team does that by creating a virtual machine and setting it very low resources, so it acts very slow. Another option is to use some kind of CPU killer – those are great pieces of software, doing exactly what it sounds – killing your CPU. There are tons of complete solutions out there, but I didn’t want to deal with the licensing and our IT stuff yelling at me, what is that software that I installed by myself again. So I decided to break the rule “ Don’t reinvent the wheel ” again. Requirements At first, here is a list ...

Using JavaFX with Maven

JavaFX is exciting new framework from Oracle, which should replace Swing one day. But unfortunatelly it is not added to Java classpath, so we need to add it manually. And because I use Maven for all my projects (right now experimenting Gradle) we want to add it as a Maven dependency.  But javaFX jar is not in any public maven repository, thus we have to install it manually to local repository. This command does the installation: mvn install:install-file -Dfile=jfxrt.jar -DgroupId=com.oracle -DartifactId=javafx -Dversion=2.2.3 -Dpackaging=jar The command was executed in the directory, where the file  jfxrt.jar  is located (on Windows the path would be something like  c:\Program Files\Java\jdk1.7.0_09\jre\lib ) otherwise the full path has to be supplied. Latest version of JavaFX runtime is 2.2.3 (included in JDK 7u9) Once the installation is done, we can use regular maven dependency attribute: <dependency> <groupId>com.oracle</g...