I'm writing a client/server application in Python and I'm finding it necessary to get a new connection to the server for each request from the client. My server is just inheriting from TCPServer and I'm inheriting from BaseRequestHandler to do my processing. I'm not calling self.request.close() anywhere in the handler, but somehow the server seems to be hanging up on my client. What's up?
views:
435answers:
4You sure the client is not hanging up on the server? This is a bit too vague to really tell what is up, but generally a server that is accepting data from a client will quit the connection of the read returns no data.
According to the docs, neither TCPServer nor BaseRequestHandler close the socket unless prompted to do so. The default implementations of both handle()
and finish()
do nothing.
A couple of things might be happening:
- You are closing the socket itself or the request which wraps it, or calling
server_close
somewhere. - The socket timeout could have been hit and you have implemented a timeout handler which closes the socket.
- The client could be actually closing the socket. Code would really help figuring this out.
However, my testing confirms your results. Once you return from handle
on the server, whether connecting through telnet or Python's socket
module, your connection shows up as being closed by the remote host. Handling socket activity in a loop inside handle seems to work:
def handle(self):
while 1:
try:
data = self.request.recv(1024)
print self.client_address, "sent", data
except:
pass
A brief Google Code Search confirms that this is a typical way of handling a request: 1 2 3 4. Honestly, there are plenty of other networking libraries available for Python that I might look to if I were facing a disconnect between the abstraction SocketServer
provides and my expectations.
Code sample that I used to test:
from SocketServer import BaseRequestHandler, TCPServer
class TestRequestHandler(BaseRequestHandler):
def handle(self):
data = self.request.recv(1024)
print self.client_address, "sent", data
self.request.send(data)
class TestServer(TCPServer):
def __init__(self, server_address, handler_class=TestRequestHandler):
TCPServer.__init__(self, server_address, handler_class)
if __name__ == "__main__":
import socket
address = ('localhost', 7734)
server = TestServer(address)
server.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Okay, I read the code (on my Mac, SocketServer.py is at /System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/). Indeed, TCPServer is closing the connection. In BaseServer#handle_request, process_request is called, which calls close_request. In the TCPServer class, close_request calls self.request.close(), and self.request is just the socket used to handle the request. So the answer to my question is "Yes".
- tcpserver really close connection each time after 'handle'
- the follow code doesn't work while peer closing
this may be better:def handle(self): while 1: try: data = self.request.recv(1024) print self.client_address, "sent", data except: pass
def handle(self): while(1): try: self.data = self.request.recv(1024) if not self.data: print "%s close" % self.client_address[0] break print "%s wrote:" % self.client_address[0], self.data except: print "except" break
- 'reuseaddr' dosen't work as it's too late after binding
server.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- 'reuseaddr' dosen't work as it's too late after binding