Tuesday, July 15, 2008

Python Socket Library Hostname quirks

Python socket library has some pretty useful functions and probably a weird behavior?:

Objective
I wanted to setup a portable way to detect whether I am connected to network or not.

When a computer is connected to some TCP/IP network (using either static or dynamic IP), it gets an IP address. Otherwise by default it has got a loopback IP address which is 127.0.0.1.

So I thought that I could use this idea for detection of presence of network.


Problem


>>> import socket # imports the socket library
>>> print socket.gethostname()
shailesh-macbook-pro.local


The above is on the my macbook-pro laptop.

If I do the same on my windows laptop I get:
>>> import socket # imports the socket library
>>> print socket.gethostname()
shailesh_lap


So far so good.

Things get weird with the following:

On Windows
>>> print socket.gethostbyname(socket.gethostname())
192.9.199.152

And on MAC Book Pro

>>> print socket.gethostbyname(socket.gethostname())
...
socket.gaierror: (8, 'nodename nor servname provided, or not known')

Now I don't really know what went wrong here. I had just sometime back restarted the system.
After some time, I found that this started working fine again

On MAC Book Pro Again after some time
>>> print socket.gethostbyname(socket.gethostname())
192.9.199.159

It is my guess that either Python on MAC, or MAC OS itself takes some time in setting up some of these IP address hostname mappings for the local host.

Work Around

But I needed to get the IP address of the host computer. My objective was to identify whether my computer is connected to some network or not. So I eventually sat down and wrote the following:


def gethostaddress():
hostname = socket.gethostname()
hostaddr = u''
try:
hostaddr = socket.gethostbyaddr(hostname)
except socket.gaierror, e:
try:
hostaddr = socket.gethostbyaddr(u'localhost')
except: pass
except: pass
return hostaddr

def networkIsPresent():
return u'127.0.0.1' == gethostaddress()




Although this may not be perfect, but I guess I will work with this for now, till I have a better solution.

5 comments:

mateor said...

Hi. I think if you reset your hostname to something shorter you will have success.
I am unsure if it is the length or perhaps banned characters, but anyway:
If you:

a) Change the hostname to `${name}-mac'
b) add that to your `/etc/hosts` file at the local ip, something like:
`127.0.0.1 ${name}-mac localhost`

Then the socket will be able to resolve your host.

`
>>> import socket
>>> socket.gethostbyname(socket.gethostname())
'127.0.0.1'
`

I know this post is really old, but I found it when searching a related
error. Since I had just resolved this problem, I wanted to give future
bug hunters a hint!

Unknown said...

Meteor's answer helped me out BIG time, thanks!

Unknown said...

I am also getting same error. What to do exactly ?

Shailesh Kumar said...

This code is inside my product which gets shipped to customers and is supposed to work out of the box. Hence it is not possible to edit the hosts file on the customer machine.

Shailesh Kumar said...

I have given the solution in the form of gethostaddress function. I can't comment further without looking at ur code.