testing for Internet connection
Alex Tweedly
alex at tweedly.net
Sun Dec 19 19:50:21 EST 2004
At 13:18 19/12/2004 -0800, Chipp Walters wrote:
>Then there's always the question, what ip address do you ping? Any
>IPaddress I have may or may not be available at a given time as
>IPAddresses are even less reliable than domains. Perhaps you know of an
>IPaddress which is 'always on'? Then, it would make a good first ping for
>the handler/function.
Most of the IP addresses of the root DNS servers should be very reliable -
recursive DNS servers will typically have these IP numbers stored in their
cache file, and will try them as necessary to get the top-level delegated
server address. Since they're stored as numeric addresses in thousands of
hosts, they need to be fairly permanent.
But - they don't always work all the time, so need to try a number of them
and if they don't succeed, then it's reasonable to assume there is no
working connection. Should have a scheme to periodically update the list of
addresses (leaving out the unreliable ones) and this should be very safe.
These addresses do change over time, but only very slowly, and typically
the "old" addresses continue to be supported (for ping and DNS requests)
for long periods (months or years).
(if the root servers are not reachable, then your DNS server is likely to
be not very operational anyway :-)
>I, like Richard, and others, have perused the lists to no final outcome
>regarding this 'am I connected' issue. I like your idea of pinging first,
>and it would be a wonderful contribution to the community to collectively
>create the best handler/function for this.
Here's a slightly modified version of your code (watch out for newlines).
Note 1. this allows an optional parameter of a numeric IP address to try
first. This can (should) be set by the app to the last successful numeric
IP address used (i.e. if the app succeeds in connecting, it should remember
that IP address, and use it next time). Although server addresses do
change, most of the time they will remain the same - and hence we avoid
putting load on the public servers. If the server address has changed -
well, we might succeed in getting a ping to work anyway - and that will
imply that we have an internet connection. If not - no harm done, we then
try the public servers. [NB client apps that are likely to be run on an
intranet should avoid this, since that can give a false-positive for having
an internet connection]
Note 2. this does the pings one after another. It would be cool to set them
off in parallel - but I don't know how (if?) that can be done in Rev. This
means the worst case time-out (i.e. if not connected to the internet) is
rather long, about 3 seconds. If this is too long, could trim out some of
the root servers, or put a limit of maybe 5 to be tried.
Note 3. If you need to deal with long latency, might need to increase the
timeout value, and/or try the "get URL" multiple times.
local rootServers =
"198.41.0.4,128.9.0.107,192.33.4.12,128.8.10.90,192.5.5.241,128.63.2.53,192.36.148.17,192.58.128.30,193.0.14.129,198.32.64.12,202.12.27.33"
-- omit "new-B", E and G.root-servers.net - they have been temperamental
function IsConnected pNumericIPAddress, pURL
-- optional pNumericIPAddress - an IP address for a previous
"interesting server"
-- optional URL to use for testing
-- hide shell activity from user
set the hideConsoleWindows to true
put "Cannot reach Internet" into tResult
-- if we have an "interesting server" try it first
if pNumericIPAddress is not empty then
put shell("ping -n 1 -w 200 " & pNumericIPAddress) into tVar
if "Received = 1" is in tVar then put empty into tResult
end if
if tResult is not empty then
sort items of rootServers by random(the number of items of rootServers)
repeat for each item I in rootServers
put shell("ping -n 1 -w 200 " & I) into tVar
if "Received = 1" is in tVar then
put empty into tResult
exit repeat
end if
end repeat
end if
-- If we have succeeded so far, let's try a "get"
if tResult is empty then
if pURL is empty then put "www.google.com" into pURL
if char 1 to 7 of pUrl <> "http://" then put "http://" before pUrl
get URL pUrl
put the result into tResult
end if
if tResult is empty then
return true
else
answer information "Problem connecting to the internet: " & tResult
return false
end if
end IsConnected
-- Alex.
More information about the use-livecode
mailing list