Python でスレッド (ThreadingMixIn) を使用して TCPServer をプログラムしようとしています。socket.error: [Errno 48] Address already in use
問題は、もう一度実行しようとするとエラーが発生するため、適切にシャットダウンできないことです。これは、問題を引き起こす python コードの最小限の例です。
import socket
import threading
import SocketServer
class FakeNetio230aHandler(SocketServer.BaseRequestHandler):
def send(self,message):
self.request.send(message+N_LINE_ENDING)
def handle(self):
self.request.send("Hello\n")
class FakeNetio230a(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
def __init__(self, server_address, RequestHandlerClass):
self.allow_reuse_address = True
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)
if __name__ == '__main__':
for i in range(2):
fake_server = FakeNetio230a(("", 1234), FakeNetio230aHandler)
server_thread = threading.Thread(target=fake_server.serve_forever)
server_thread.setDaemon(True)
server_thread.start()
# might add some client connection here
fake_server.shutdown()
メイン コードで行う必要があるのは、サーバーを起動し、シャットダウンして、再度実行することだけです。ただし、最初のシャットダウン後にソケットが解放されていないため、上記のエラーが発生します。
self.allow_reuse_address = True
設定すれば解決できると思ったのですが、うまくいきませんでした。Python プログラムが終了したら、すぐにもう一度実行して、サーバーを 1 回 (ただし、2 回ではなく) 起動できます。
ただし、他のサーバーがそのアドレスでリッスンしていないため、ポートをランダム化すると (たとえば、に置き換えると) 1234
、問題はなくなります。1234+i
同様の SO Q Shutting down gracefully from ThreadingTCPServerがありますが、解決策があります (自分のコードでは機能せず、ThreadingTCPServer を使用しallow_reuse_address
てTrue
いません)。
コードでサーバーを 2 回起動できるようにするには、コードをどのように変更する必要がありますか?
Some more information: The reason why I'm doing this is that I want to run some unit tests for my python project. This requires to provide a (fake) server that my software should to connect to.
edit:
I just found the most correct answer to my problem: I have to add fake_server.server_close()
at the end of my main execution code (right after fake_server.shutdown()
). I found it in the source file of the TCPServer
implementation. All it does is self.socket.close()
.