python - Connections outlive SocketServer.TCPServer? -


how can make tcp server close sockets?

i wrote simple tcp server echo information client. use on localhost:8088 , stop using killall , restart @ time i'm working on code.

however, i'm having trouble making close sockets , "free" address, when make few tests, fix in code , stop (ctrl+c) , start server again, socket.error: [errno 98] address in use.

when sudo netstat -ntap, can still see few 127.0.0.1:8088 sockets in time_wait state. have wait until "die out".

my test case:

#!/usr/bin/python import socketserver  class myechohandler(socketserver.baserequesthandler):      def handle(self):         self.data = self.request.recv(1024).strip()         # smart data, now, hello.         self.reply = "content-type: text/plain\r\n\r\nhello."         self.request.send(self.reply)         self.request.close()  def main():     server = socketserver.tcpserver((host, port), myechohandler)     server.serve_forever()  if __name__ == '__main__':     host, port = "localhost", 8088     main() 

what doing wrong? shouldn't self.request.close() enough?

i'm trying on debian python 2.7.3, although need support squeeze python 2.6 well.

the tcp stack puts port timed-wait awhile (something 30 seconds multiple minutes depending on system). can change behavior so_reuseaddr socket option. trick option must set before port bound.

if have raw socket, can:

s.setsockopt(socket.sol_socket, socket.so_reuseaddr, 1)  

socketserver lets set option globally allow_reuse_address attribute:

socketserver.tcpserver.allow_reuse_address = true 

or can when create server:

def main():     server = socketserver.tcpserver((host, port), myechohandler, false)     server.allow_reuse_address = true     server.server_bind()     server.serve_forever() 

or override bind method:

class mytcpserver(socketserver.tcpserver):      def server_bind(self):         self.allow_reuse_address = true         super(mytcpserver, self).server_bind() 

here 3 solutions worked me on windows machine.

(1) set globally

#!/usr/bin/python import socketserver import time  socketserver.allow_reuse_address = true  class myechohandler(socketserver.baserequesthandler):      def handle(self):         self.data = self.request.recv(1024).strip()         # smart data, now, hello.         self.reply = "content-type: text/plain\r\n\r\n" + time.asctime()         self.request.send(self.reply)         self.request.close()  def main():     server = socketserver.tcpserver((host, port), myechohandler)     server.serve_forever()  if __name__ == '__main__':     host, port = "localhost", 8088     main() 

(2) set locally

#!/usr/bin/python import socketserver import time  class myechohandler(socketserver.baserequesthandler):      def handle(self):         self.data = self.request.recv(1024).strip()         # smart data, now, hello.         self.reply = "content-type: text/plain\r\n\r\n" + time.asctime()         self.request.send(self.reply)         self.request.close()  def main():     server = socketserver.tcpserver((host, port), myechohandler, false)     server.allow_reuse_address = true     server.server_bind()     server.server_activate()     server.serve_forever()  if __name__ == '__main__':     host, port = "localhost", 8088     main() 

(3) inherit

#!/usr/bin/python import socketserver import time  class myechohandler(socketserver.baserequesthandler):      def handle(self):         self.data = self.request.recv(1024).strip()         # smart data, now, hello.         self.reply = "content-type: text/plain\r\n\r\n" + time.asctime()         self.request.send(self.reply)         self.request.close()  class mytcpserver(socketserver.tcpserver):      def server_bind(self):         self.allow_reuse_address = true         socketserver.tcpserver.server_bind(self)  def main():     server = mytcpserver((host, port), myechohandler)     server.serve_forever()  if __name__ == '__main__':     host, port = "localhost", 8088     main() 

Comments