Introduction to Sockets

In many of the previous examples, you connected to a server on a particular port of a particular machine (for instance, port 25 of localhost for a local SMTP server). When you tell imaplib or smtplib to connect to a port on a certain host, behind the scenes Python is opening a connection to that host and port. Once the connection is made, the server opens a reciprocal connection to your computer. A single Python "socket" object hides the outgoing and incoming connections under a single interface. A socket is like a file you can read to and write from at the same time.

To implement a client for a TCP/IP-based protocol, you open a socket to an appropriate server. You write data to the socket to send it to the server, and read from the socket the data the server sends you. To implement a server, it's just the opposite: You bind a socket to a hostname and a port and wait for a client to connect to it. Once you have a client on the line, you read from your socket to get data from the client, and write to the socket to send data back.

It takes an enormous amount of work to send a single byte over the network, but between TCP/IP and the socket library, you get to skip almost all of it. You don't have to figure out how to get your data halfway across the world to its destination, because TCP/IP handles that for you. Nor need you worry about turning your data into TCP/IP packets, because the socket library handles that for you.

Just as e-mail and the Web are the killer apps for the use of the Internet, sockets might be considered the killer app for the adoption of TCP/IP. Sockets were introduced in an early version of BSD UNIX, but since then just about every TCP/IP implementation has used sockets as its metaphor for how to write network programs. Sockets make it easy to use TCP/IP (at least, easier than any alternative), and this has been a major driver of TCP/IP's popularity.

As a first socket example, here's a super-simple socket server, SuperSimpleSocketServer.py:

#!/usr/bin/python import socket import sys if len(sys.argv) > 3:

print('Usage: %s [hostname] [port number]' % sys.argv[0]) sys.exit(l)

#Set up a standard Internet socket. The setsockopt call lets this #server use the given port even if it was recently used by another #server (for instance, an earlier incarnation of #SuperSimpleSocketServer).

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #Bind the socket to a port, and bid it listen for connections. sock.bind((hostname, port)) sock.listen(1)

print("Waiting for a request.") #Handle a single request, request, clientAddress = sock.accept() print("Received request from", clientAddress)

request.send(bytes('-=SuperSimpleSocketServer 3000=-\n', 'utf-8')) request.send(bytes('Go away!\n', 'utf-8'))

request.shutdown(2) #Stop the client from reading or writing anything.

print("Have handled request, stopping server.")

sock.close()

This server will serve only a single request. As soon as any client connects to the port to which it' s bound, it will tell the client to go away, close the connection, stop serving requests, and exit.

Try It Out Connecting to the SuperSimpleSocketServer with Telnet

The telnet program is a very simple client for TCP/IP applications. You invoke it with a hostname and a port; it connects you to that port; and then you're on your own. Anything you type is sent over a socket to the server, and anything the server sends over the socket is printed to your terminal. Telnet is included as a command-line program in Windows, Mac OS X, and UNIX installations, so you shouldn't have trouble getting it.

Because the example socket server doesn't really do anything, there's little point in writing a custom client for it. To test it out, just start up the server:

$ python SuperSimpleSocketServer.py localhost 2000 Waiting for a request.

Then, in a separate terminal, telnet into the server:

$ telnet localhost 2000 Trying 127.0.0.1... Connected to rubberfish. Escape character is ,A]'. -=SuperSimpleSocketServer 3000=-Go away!

Connection closed by foreign host.

Go back to the terminal on which you ran the server and you should see output similar to this:

Received request from ('127.0.0.1', 32958) Have handled request, stopping server.

0 0

Post a comment