Simple TCP Server in python

Ravi Kulkarni picture Ravi Kulkarni · Mar 18, 2013 · Viewed 12.4k times · Source

Newbie here. I am trying to create a simple TCP server is process requests using SocketServer. Somehow, the handle() method is not getting called.

Version: 2.4.3 on Linux

Here is the relevant code:

#!/usr/bin/python -u
import socket;
import SocketServer
import time;
import threading;
class EchoRequestHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        # Echo the back to the client
        data = self.request.recv(1024)
        self.request.send(data)
        return
class MyThreads(threading.Thread):
    def __init__(self):
        self.server = None;
        threading.Thread.__init__(self);
    def run(self):
        if self.server == None:
            address = ('localhost', 40000);
            self.server = SocketServer.TCPServer(address, EchoRequestHandler);
            # The following line partially fixed the problem
            self.server.serve_forever();
if __name__ == '__main__':
    thr = MyThreads();
    thr.setDaemon(True);
    thr.start();
    # Connect to the server
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(('localhost', 40000))
    # Send the data
    message = 'Hello, world'
    print 'Sending : "%s"' % message
    len_sent = s.send(message)
    # Receive a response
    print 'Sending : "%s"' % message
    response = s.recv(len_sent)
    print 'Received: "%s"' % response

The code is creating the socket, I can see it from the commandline using netstat. But in the debugger (python -m pdb) I can't see the code in method run() executing at all. And the handle() is not getting called either. So it connects to the socket, but doesn't receive anything back.

Answer

larsks picture larsks · Mar 18, 2013

You need to call serve_forever() to get your SocketServer object to start listening for connections. The serve_forever() method, as its name implies, will never return. Given this fact, you probably want to call it in your thread in order to allow the rest of your code to proceed. For example:

class MyThreads(threading.Thread):
    def __init__(self):
        self.server = None;
        threading.Thread.__init__(self);
    def run(self):
        if self.server == None:
            address = ('localhost', 40000);
            self.server = SocketServer.TCPServer(address, EchoRequestHandler);

        self.server.serve_forever()

You may run into race conditions here if your client code attempts to connect before the socket is listening. Possibly time.sleep(...) will help you here.