Chapter 4 ■ SoCket NameS aNd dNS
66
import argparse, socket, sys
def connect_to(hostname_or_ip):
try:
infolist = socket.getaddrinfo(
hostname_or_ip, 'www', 0, socket.SOCK_STREAM, 0,
socket.AI_ADDRCONFIG | socket.AI_V4MAPPED | socket.AI_CANONNAME,
)
except socket.gaierror as e:
print('Name service failure:', e.args[1])
sys.exit(1)
info = infolist[0] # per standard recommendation, try the first one
socket_args = info[0:3]
address = info[4]
s = socket.socket(*socket_args)
try:
s.connect(address)
except socket.error as e:
print('Network failure:', e.args[1])
else:
print('Success: host', info[3], 'is listening on port 80')
if name == 'main':
parser = argparse.ArgumentParser(description='Try connecting to port 80')
parser.add_argument('hostname', help='hostname that you want to contact')
connect_to(parser.parse_args().hostname)
This script performs a simple “Are you there?” test of whatever web server you name on the command line by
attempting a quick connection to port 80 with a streaming socket. Using the script would look something like this:
$ python www_ping.py mit.edu
Success: host mit.edu is listening on port 80
$ python www_ping.py smtp.google.com
Network failure: Connection timed out
$ python www_ping.py no-such-host.com
Name service failure: Name or service not known
Note three things about this script:
• It is completely general, and it contains no mention either of IP as a protocol or of TCP as a
transport. If the user happened to type a hostname that the system recognized as a host to
which it was connected through AppleTalk (if you can imagine that sort of thing in this day
and age), then getaddrinfo() would be free to return the AppleTalk socket family, type,
and protocol, and that would be the kind of socket that you would wind up creating and
connecting.
• getaddrinfo() failures cause a specific name service error, which Python calls a gaierror,
rather than a plain socket error of the kind used for the normal network failure detected at the
end of the script. You will learn more about error handling in Chapter 5.