Форум сайта python.su
Приветствую.
Столкнулся с ошибкой при перезапуске примера из http://docs.python.org/library/socketserver.html#socketserver-tcpserver-example после подключения telnetom на порт 9999.
File "/usr/local/lib/python2.6/SocketServer.py", line 411, in server_bind
self.socket.bind(self.server_address)
File "<string>", line 1, in bind
socket.error: [Errno 98] Address already in use
.........
allow_reuse_address = False
.........
def server_bind(self):
"""Called by constructor to bind the socket.
May be overridden.
"""
if self.allow_reuse_address:
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(self.server_address) # 411 строка
self.server_address = self.socket.getsockname()
netstat -ne | grep 9999
tcp 0 0 127.0.0.1:9999 127.0.0.1:47237 TIME_WAIT 0 0
Офлайн
В той же доке парой десятков строк выше:
BaseServer.allow_reuse_address
Whether the server will allow the reuse of an address. This defaults to False, and can be set in subclasses to change the policy.
Офлайн
эх путаюсь я с этими классами, в общем заработало, но не уверен что я правильно сделал.
.....
SocketServer.TCPServer.allow_reuse_address=True
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
Офлайн
Так тоже можно, но правильно (по английски читаете?) переопределить в классе-наследнике.
Офлайн
вот что у меня получилось - наверное это и есть это загадочное ООП).
в тот же файл примера добавляю свой класс
class MyTCPServer(SocketServer.TCPServer):
allow_reuse_address = 1
def __init__(self, host='localhost',
port=9999,
handler=MyTCPHandler):
SocketServer.TCPServer.__init__(self, (host, port), handler)
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = MyTCPServer(host = HOST, port = PORT, handler = MyTCPHandler)
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
Офлайн
Чем дальше в лес, тем больше дров.
столкнулся с новой трудностью, как завершить работу программы, например по приходу сообщения “exit”.
метод shutdown() напрямую не срабатывает.
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print "%s wrote:" % self.client_address[0]
print self.data
# just send back the same data, but upper-cased
self.request.send(self.data.upper())
if self.data=='exit':
self.shutdown()
#raise
def serve_until_stopped(self):
import select
serving = 0
while not serving:
rd, wr, ex = select.select([self.socket.fileno()],
[], [],
self.timeout)
if rd:
self.handle_request()
serving = self.serving
Офлайн
class MyTCPServer(SocketServer.TCPServer):
allow_reuse_address = 1
def __init__(self, host, port):
SocketServer.TCPServer.__init__(self, (host, port), MyTCPHandler)
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
server = MyTCPServer(HOST, PORT)
server.serve_forever()
Офлайн
Андрей СветловСпасибо с этим надеюсь разобрался, я не могу понять как остановить server.serve_forever() по событию.
Код:
class MyTCPServer(SocketServer.TCPServer):
allow_reuse_address = 1
def __init__(self, host, port):
SocketServer.TCPServer.__init__(self, (host, port), MyTCPHandler)
if __name__ == “__main__”:
HOST, PORT = “localhost”, 9999
server = MyTCPServer(HOST, PORT)
server.serve_forever()
def main():
HOST, PORT = "localhost", 9999
server = MyTCPServer(host = HOST, port = PORT, handler = MyTCPHandler)
print 'start server'
thr_server = threading.Thread(target=server.serve_forever)
thr_server.daemon = True
thr_server.start()
while 1:
try: time.sleep(3600)
except (KeyboardInterrupt, SystemExit):
print 'stop server'
server.shutdown()
break
return 0
if __name__ == "__main__":
sys.exit(main())
Офлайн
Разобрался, в общем для того чтобы остановить .serve_forever(), пришлось использовать threading и задействовать глобальную переменную. Вместо глобальной переменной думаю есть еще варианты.
import SocketServer, time, threading
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024).strip()
print "%s wrote:" % self.client_address[0]
print self.data
self.request.send(self.data.upper()+'\n')
def finish(self):
global exit
if self.data=='exit':
exit = 1
class MyTCPServer(SocketServer.ThreadingTCPServer):
allow_reuse_address = 1
def __init__(self, host, port, handler):
SocketServer.ThreadingTCPServer.__init__(self, (host, port), handler)
def main():
global exit
exit = 0
HOST, PORT = "localhost", 9999
server = MyTCPServer(host = HOST, port = PORT, handler = MyTCPHandler)
thr_recv = threading.Thread(target=server.serve_forever)
thr_recv.daemon = True
print '%s started at %s' % (server.__class__.__name__, server.server_address)
thr_recv.start()
while not exit:
if exit:
print 'stop server'
server.shutdown()
break
time.sleep(5)
return 0
if __name__ == "__main__":
main()
Офлайн
Варианты всегда есть.
Просто, поймите правильно, socketserver - детская поделка. Много из него не выжмешь.
Офлайн