BYUBRIGHAM YOUNG UNIVERSITY
Computer Science
Python Network Programming

The Socket Module

A Simple Echo Server

Here is a simple echo server (echoserver-simple.py):

#!/usr/bin/env python

"""
A simple echo server
"""

import socket

host = ''
port = 50000
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
while 1:
    client, address = s.accept()
    data = client.recv(size)
    if data:
        client.send(data)
    client.close()

Let's go through this code a few lines at a time:

#!/usr/bin/env python

"""
A simple echo server
"""

The first line allows us to execute the server directly by typing "echoserver.py" at the command line (on Solaris and Linux systems, the script must also have execute permission set using "chmod u+x echoserver.py). Without this line, the server would have to be run with "python echoserver.py".

The rest of the above code is simply a comment. Comments can start with a "#" or enclosed in triple quotes as above.

import socket

host = ''
port = 50000
backlog = 5
size = 1024

Next, the server imports the socket module, then sets the host name and the port number. By setting the host name to the empty string, it tells the bind() method to fill in the address of the current machine. This is an easy way of setting up a server so that runs on whichever host you use. For the port number, simply choose some large number (less than 216) that you hope no one else is using. The backlog and size parameters will be used later.

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

This creates a socket object, stored in s, that will use TCP and IPv4.

s.bind((host,port))

This binds the socket to the host name (the current host) and the port number specified above. This allows your application to accept incoming connections that designate your host address and the indicated port number as the server. Note that this call will fail if some other application is already using this port number on the same machine. We will discuss handling exceptions later.

s.listen(backlog)

This tells the operating system to keep a backlog of five connections. This means that you can have at most five clients waiting while the server is handling the current client. You can set this higher, but the operating system will typically allow a maximum of 5 waiting connections. To cope with this, busy servers need to generate a new thread to handle each incoming connection so that it can quickly serve the queue of waiting clients. We will discuss threading later.

while 1:
    client, address = s.accept()
    data = client.recv(size)
    if data:
        client.send(data)
    client.close()

This infinite while loop accepts a client, reads a single message, then echoes that message back to the client.

The accept() method accepts an incoming connection (a client). Notice that the call returns a pair of arguments: client is a new socket object used to communicate with the client and address is the address of the client. For TCP sockets, you don't need the address of the client in order to communicate with it, but you may want to keep track of client identities.

The socket recv() method takes the maximum amount of data, in bytes, that you are willing to receive. Note that the actual amount of data you receive may be less than the maximum size you specify. In this example the server does not echo the data back to the client if the recv() method does not return any data; this will happen, for example, if the client closes the socket.

The socket send() method sends data to the client. Note that the return value of send() is the number of bytes actually sent. In this short example, we are not checking this return value and are assuming that all data was sent successfully.

This socket close() method will close the socket. All future operations on the socket will fail.

Note that in this simple example the client is only allowed to send up to 1024 bytes. A better server would allow the client to echo as many messages as it wanted to.