重启基于socketserver的Python TCP服务器报WinError 10048错误
问题产生原因
抛出WinError 10048的核心原因有两个:
socketserver的shutdown()方法仅会终止serve_forever()的事件监听循环,不会主动关闭底层绑定的监听socket,端口资源没有被进程主动释放。Windows系统对端口占用的校验规则较严格,未显式关闭的socket对应的端口会被系统标记为占用状态,短时间内不允许其他进程(甚至同进程)重新绑定。- 自定义的
ThreadedTCPServer没有开启地址复用配置,默认情况下操作系统不允许绑定处于临时保留状态(TIME_WAIT)的端口,进一步放大了重启时的端口冲突问题。
正确的TCP服务器重启实现
只需要做两处修改即可解决问题:
- 在自定义的ThreadedTCPServer类中开启
allow_reuse_address = True配置,socketserver初始化时会自动给底层socket设置SO_REUSEADDR选项,允许服务重启时快速绑定同端口,不用等待系统TIME_WAIT超时。 - 在服务关闭逻辑中,
shutdown()执行完成、服务线程退出后,必须调用server_close()方法,主动释放底层socket占用的端口资源。
修正后的完整代码
import threading import socketserver import time class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler): def setup(self): pass def handle(self): pass def finish(self): pass class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): # 开启地址复用,允许快速重启绑定同端口 allow_reuse_address = True class Transport_Server: def __init__(self): HOST, PORT = "0.0.0.0", 5001 self.server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler) ip, port = self.server.server_address self.server_thread = threading.Thread(target=self.server.serve_forever) self.server_thread.daemon = True self.server_thread.start() print("Server loop running in thread:", self.server_thread.name) def shutdown(self): # 停止监听循环 self.server.shutdown() # 等待服务线程退出 self.server_thread.join() # 主动关闭底层socket,释放端口 self.server.server_close() if __name__ == "__main__": transport = Transport_Server() print("Server started") time.sleep(5) print("Shutting down") transport.shutdown() print("Waiting") time.sleep(5) transport = Transport_Server() print("Server restarted")
补充说明:生产环境使用时建议在
handle()方法内增加异常捕获,避免单个连接报错导致整个服务线程崩溃;多线程场景下注意给共享资源加锁,防止并发读写冲突。
内容的提问来源于stack exchange,提问作者dashman
相关产品推荐
相关产品推荐

