- Home /
Ping class producing false positives, alternative to check connectivity?
I'm checking for online connectivity using Application.internetReachability against both LAN and Data Networks. Unfortunately I've found that if the client is connected to a network, but that network is not connected to the internet, the program still assumes the client is connected.
I've tried countering this by running a ping test, but the ping periodically returns false positives, saying the ping was successful after x time even when the computer or device is entirely disconnected.
Exploring further, while disconnected from the internet I pinged an ip from command prompt, which produced the following results:
Request timed out.
Reply from 192.168.0.123: Destination host unreachable.
Reply from 192.168.0.123: Destination host unreachable.
Reply from 192.168.0.123: Destination host unreachable.
The Unity Ping class seemingly cannot differentiate between an "unreachable" reply, and a positive reply. Is there an alternative means of checking for connectivity?
Cheers.
Do you resolve an URL / domain name or do you use a fix IP? If you do a domain lookup beforehand, you should check if the lookup was successful.
An
echo request(IC$$anonymous$$P type 8) was never ment to check internet connectivity. It has two main purposes: Check the reachabillity to a certain host and to measure the
Unity's Ping class doesn't return any kind of success or failure indicator, so it's only purpose seems to be measuring the RTT.
If you still want to use a ping, you might want to use a .NET class ins$$anonymous$$d.
Just in case you haven't seen it, Unity has a
TestConnection function which returns quite detailed information about the connectivity.
edit
I just like to quote the docs of Application.internetReachability:
"Note: Do not use this property to deter$$anonymous$$e the actual connectivity. $$anonymous$$g. the device can be connected to a hot spot, but not have the actual route to the network."
Answer by tonic · Aug 18, 2014 at 11:01 AM
(Adding a comment to an old posting in case somebody finds this using search...)
To truly know internet can be reached, there needs to be "captive portal detection". It's a technique also used by operating systems, where you simply do a request to an url which gives a reply with known contents. That helps to know if you're e.g. hitting a public WiFi login page. Just checking Application.internetReachability or doing a Ping doesn't guarantee that internet connection works.
I have made an easy asset called Internet Reachability Verifier and it allows you to use one of the captive portal detection methods maintained by big OS vendors, or your own custom url. It keeps you up-to-date whether you have verified internet access and it works with desktop and mobile platforms (self-hosted custom method can be used with the web player plugin if you think that's necessary). If you want to give it a try, there's more info here: http://j.mp/IRVUN
Answer by mindlube · Jul 24, 2012 at 10:03 PM
If you can replicate that about the unreachable and Ping, that sounds like a good bug report to submit.
beyond what you've stated already, I suggest just using WWW class and try downloading a very small web page might make a good test
or connect to your multiplayer server, or whatever you will be using the network for, and fail gracefully if connection is not there.
I think I'll probably go ahead and submit a bug report, because it just seems like an oversight to me.
As for using the WWW class to download a small page, I had considered that, but will approach it as a last resort. It seems very hack-y, and I'm afraid if used in place of a ping check it may hit our server harder than we'd like.
We're using a third party multiplayer server system, so attempting to handle the errors it throws could pose to be an issue, but it's worth exploring.
Thanks for your suggestions! I'm glad, at least, that I'm not crazy, and there is potentially a real issue here.
Answer by numberlessuser · Jul 26, 2012 at 12:14 AM
Are you just watching for Ping.isDone()? If a ping times out internally it will still register as finished for isDone(). You need to check Ping.time. If the ping timed out it's time should still be listed as -1, whereas if it was successful it will show how long it took before success.
I'm watching for isDone(), and then logging its time which produces differing amounts; I've seen 300ms to 500ms. It doesn't appear to be ti$$anonymous$$g out naturally producing -1, which is what encouraged me to check the command prompt, and in turn led me to find the false positive replies.
On android it returns -1 when the ping fails, but i noticed that it returns -1 and the ping fails when you are connected to the internet Via Carrier Data Network too, which is weird, so i recommend using the .NET ping class.