2

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.

Ravi Kulkarni
  • 43
  • 1
  • 1
  • 6
  • 4
    Have you looked at the example [here](http://docs.python.org/2/library/socketserver.html)? I don't see a call to `serve_forever()` in your code. – larsks Mar 18 '13 at 20:27
  • Also, you don't need semicolons after `import` statements. – larsks Mar 18 '13 at 20:28
  • I know, it is just a carryover from other programming habits. I am not able to figure out where to use serve_forever() in this code. I am a bit confused. – Ravi Kulkarni Mar 18 '13 at 20:31
  • 2
    You should try to break those habits, especially when you're posting code here in SO. – larsks Mar 18 '13 at 20:33
  • Oops, you are right, serve_forever() did seem to fix it. But now I have a new problem. It seems to get out immediately after sending and receiving one message. It is not serving forever. – Ravi Kulkarni Mar 18 '13 at 20:35
  • Your main thread exits after printing `Received:`. If you want your program to run continuously, you need to not do that. It's not even clear why you're using threads here; you would be better off moving the client code to another script and just have have `serve_forever` be the last thing called by your server script. – larsks Mar 18 '13 at 20:37

1 Answers1

2

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.

larsks
  • 277,717
  • 41
  • 399
  • 399
  • When I try to send the message a second time, I get this error: Traceback (most recent call last): File "./testTCP.py", line 47, in ? response = s.recv(len_sent) socket.error: (104, 'Connection reset by peer') – Ravi Kulkarni Mar 18 '13 at 20:47
  • Thanks for your help @larsks, I rewrote the code as you suggested and it works now. – Ravi Kulkarni Mar 18 '13 at 21:39