如何在Python中重置套接字地址?解决WinError 10048问题
解决Socket端口占用(WinError 10048)问题
这个错误的核心原因是:当你的服务端程序关闭后,操作系统会把占用的端口保留一段时间(处于TIME_WAIT状态),目的是处理网络中残留的数据包,防止它们干扰新建立的连接。这时候你再次尝试绑定同一个端口,就会触发“地址已被占用”的报错。
下面给你几个彻底解决的方案,按推荐优先级排序:
1. 给套接字设置SO_REUSEADDR选项(最推荐)
这是代码层面的最优解,让操作系统允许你立即重用处于TIME_WAIT状态的端口。你只需要在服务端创建socket后、绑定端口前,添加一行设置代码:
修改后的server.py关键部分:
host, port = ('', 8486) server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 添加这一行,允许端口重用 server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind((host, port))
这个设置会告诉操作系统:即使该端口还处于TIME_WAIT状态,也允许新的套接字绑定上去,完美解决重复启动的问题。
2. 修复服务端的资源关闭逻辑
你当前的server.py有个小问题:conn.close()和socket.close()写在while循环外面,而你的循环是while run :(run一直为True),所以这两行代码永远不会被执行到。这会导致服务端意外关闭时,资源没有被正确释放,反而加重端口占用的概率。
可以给服务端加上退出处理,比如捕获KeyboardInterrupt(按下Ctrl+C退出),确保资源被正确关闭:
修改后的完整server.py:
import socket from threading import Thread class Serv(Thread): def __init__(self, conn): Thread.__init__(self) self.conn = conn def run(self): try: data = self.conn.recv(1024) data = data.decode("utf8") print(data) finally: self.conn.close() # 每个线程的连接单独关闭 host, port = ('', 8486) server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind((host, port)) run = True try: while run : server_socket.listen(5) conn, address = server_socket.accept() thread_serv = Serv(conn) thread_serv.start() except KeyboardInterrupt: print("正在关闭服务端...") run = False finally: server_socket.close() # 确保主套接字被关闭
注意我把原来的变量名socket改成了server_socket,避免和模块名冲突,这是个好的编程习惯。
3. 手动释放端口(临时应急)
如果你临时不想改代码,可以手动找到占用8486端口的进程并杀掉:
- 打开命令提示符(CMD),执行:
netstat -ano | findstr :8486 - 找到输出结果中的PID(最后一列数字)
- 执行:
taskkill /F /PID <你的PID数字>
不过这个方法只能临时解决,下次启动可能还会遇到问题,不如前两个方案彻底。
内容的提问来源于stack exchange,提问作者user10620375




