Checking if the computer is online

Dave Brueck dave at pythonapocrypha.com
Wed Sep 17 15:35:50 CEST 2003


On Thursday 18 September 2003 01:10 am, Thomas Heller wrote:
> Mickel Grönroos <mickel at csc.fi> writes:
> > Hi all,
> >
> > I have a silly question. Is there are simple way to check if the computer
> > is connected to the Internet? It seems this should be a pretty
> > straight-forward thing to do, but as I am totally unfamiliar with sockets
> > and such, I ask for your help before getting my hands dirty.
>
> For windows?
>
> <http://article.gmane.org/gmane.comp.python.windows/969>

The problem with the InternetGetConnectedState API is that, at least on older 
versions of Windows/Internet Explorer, it relies on the settings of Internet 
Explorer rather than the true state of the connection. In other words, it 
would return an incorrect answer if Netscape was the only browser ever used. 
Also, it doesn't work in a connection sharing setup (e.g. your computer is on 
a home LAN that is connected to another computer with a modem.

Maybe this is way more than the OP needs, but I'll post it anyway because it's 
tough to reliably detect the connected state. After much painstaking 
experimentation :) I came up with a fairly decent method of knowing if the 
current computer is really connected to the Internet using a combination of 
all sorts of info available (works on Windows using ctypes). It turns out 
that there is no single API to call, and some APIs give unreliable info, and 
others will cause your modem to go online if you're not online, so they must 
be avoided. 

Here's a breakdown of the determination process that works for me:

- First and foremost, if your application is currently downloading or 
uploading then you know you're online. At first it seems silly, but it's 
actually a pretty reliable nugget of info, so my connection detection lib has 
a SetOnlineHint(isOnline) API that the app calls periodically (internally my 
library uses an exponential moving average to "degrade" this value over time 
so that if it falls below some threshold then the library doesn't consider it 
to be accurate enough to rely on and moves to the next method of detection).

- Call the GetTcpTable API and get a list of all IP addresses whose rows have 
the dwState of MIB_TCP_STATE_ESTAB. Then filter out all IP addresses 
127.0.0.1, 10.* 192.168.*, and 172.16* through 172.31.*. If the remaining 
list is non-empty, something on this computer is most likely connected to a 
public IP address, so it's fairly safe to assume you're online

- If RasEnumConnections gives a non-empty list then you're online (but don't 
assume the converse is true)

- If the IsNetworkAlive API is supported and returns false, you're not online 
(But you can't rely on a "yes" answer from this API)

- If all the above don't yield any definite answers, then ping a known IP 
address (either by using raw sockets or by just calling os.popen('ping ...') 
and reading the output. Ping is nice because ICMP packets won't cause the 
modem to autodial if you're not online. My library has as a default the IP 
addresses of a bunch of well known servers (e.g. DNS root servers) to use in 
emergencies, but these are best avoided in all but the most extreme 
emergencies when it has no other IPs to use - it collects public IP addresses 
from the GetTcpTable call above, for example.

The library runs through this determination process every second or so in its 
own thread, pinging at most once every 5 or 10 seconds, and the application 
just queries a IsOnline API.

Convoluted, but it works, so it was worth the effort to put it in a separate 
library and never figure it out again. :)

-Dave





More information about the Python-list mailing list