Skip navigation.

Simple TCP server written in Python, using socket and select

,

Today I started writing a small server using TCP sockets in Python. Nothing very big, nothing very special, and still far from finished, but I thought I should share the code I have now. Currently, I have an uber-simple server that listens to a TCP port and can accept multiple connections (IPv4 only). All running in a single thread and using only 20 lines of Python code.

Introduction

I'm supposing you know Python somewhat well, and know how TCP/IP works. No need to be an expert, but a good understanding of how it works helps a lot. For testing, a telnet or netcat client is handy.

Before writing the code below, I read these pages:

How it works

At first, the server will create a socket object to bind itself to a port on local machine, accepting connections from any IP. This socket can only be used to listen for new connections; no data is sent or received through this socket.

Then the server enters an infinite loop, using select() to wait for I/O.

When a new connection is received, the .accept() method will return a new socket object that is specific for this new connection. This new socket can be used for sending and receiving data, while the old listening socket is kept intact. This new socket is added to a list of currently open sockets.

When data is received from an open socket, the data is read using .recv() and then printed to the server terminal. If .recv() returns no data (empty string), it means that the connection was closed (unfortunately, this is not described at Python documentation, but it is described at recv(2) man page).

No exception handling is done. Actually, right now I don't even know if this code can generate exceptions. (information regarding this is very appreciated)

The code

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket, select

# List of socket objects that are currently open
open_sockets = []

# AF_INET means IPv4.
# SOCK_STREAM means a TCP connection.
# SOCK_DGRAM would mean an UDP "connection".
listening_socket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )

# The parameter is (host, port).
# The host, when empty or when 0.0.0.0, means to accept connections for
# all IP addresses of current machine. Otherwise, the socket will bind
# itself only to one IP.
# The port must greater than 1023 if you plan running this script as a
# normal user. Ports below 1024 require root privileges.
listening_socket.bind( ("", 1234) )

# The parameter defines how many new connections can wait in queue.
# Note that this is NOT the number of open connections (which has no limit).
# Read listen(2) man page for more information.
listening_socket.listen(5)


while True:
    # Waits for I/O being available for reading from any socket object.
    rlist, wlist, xlist = select.select( [listening_socket] + open_sockets, [], [] )
    for i in rlist:
        if i is listening_socket:
            new_socket, addr = listening_socket.accept()
            open_sockets.append(new_socket)
        else:
            data = i.recv(1024)
            if data == "":
                open_sockets.remove(i)
                print "Connection closed"
            else:
                print repr(data)

Testing

You can write a Python client to test this server, you can just use netcat. Run the following command at your shell:
nc 127.0.0.1 1234
Then type something and press Enter. To close the netcat, press Ctrl-C.

Try opening multiple simultaneous connections, and also from different hosts, just to see that things actually work, even with such simple code.

And that's all, folks! I hope this code is useful for someone else, as it shows how select() and sockets can be combined. Have fun!

Comparison of Java equality comparisonRunning md5sum on Nokia phone using Python S60

Comments

Aadil 11. February 2009, 16:36

I want to get back into programming but I've no idea where to start. My limited background is the seriously obsolete Commodore 64 which taught me BASIC and 6502 machine code. I also did a COBAL course many moons ago but I can't recall much of that. I'll need to buy hardware, software and some books to get started. I don't have any sort of computer at all yet. (I use my mobile to in online.) I'd particularly like to get involved in programming for mobile devices. Can you give me some idea of what to do to get started?

Anonymous 19. August 2009, 11:07

Rajkumar writes:

I'm new to phython and currently working with asp.net.

Can i use this code to open a socket at the client side of my web application keep the port open until he shuts the window. Can we categorize phython into a client server architecture?

If phython can be used to open a socket and we can keep communicating to it from any remote location or an asp.net application then it would be a great thing as it will improve the performance of the server by keeping the number of requests to be low cause all the current asp.net chat applications need to post back to the server every 2 seconds to check whether there is any message for him or not.

if there is some solution or you couldn't get what am i saying please mail me at koolraj@gmail.com

Denilson Figueiredo de Sá 20. August 2009, 00:06

Rajkumar,

If you are working with web applications (that should run inside a web browser), you should (I mean... you MUST) stick to JavaScript for the client-side.

Thus, by your description it seems you want this:
http://en.wikipedia.org/wiki/Comet_(programming)

Sorry, I can't help you more than this.

Anonymous 20. August 2009, 10:01

Rajkumar writes:

Thanks for letting me know.

How to use Quote function:

  1. Select some text
  2. Click on the Quote link

Write a comment

Comment
(BBcode and HTML is turned off for anonymous user comments.)

If you can't read the words, press the small reload icon.


Smilies

January 2010
S M T W T F S
December 2009February 2010
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30