Debian服务器上Python设置SO_REUSEADDR后仍出现“地址已被占用”错误求助
Debian服务器上Python设置SO_REUSEADDR后仍出现“地址已被占用”错误求助
我完全懂你这种困扰——脚本崩了之后端口就一直被占,明明加了SO_REUSEADDR还是没用,试了好几次都卡在这里,确实挺闹心的。咱们一步步来排查解决这个问题:
首先,确认端口是不是被残留进程占用了
很多时候出现这个错误,并不是SO_REUSEADDR没生效,而是之前崩溃的Python进程根本没完全退出,还攥着端口不放。你可以用这两个命令检查:
- 用
lsof查看端口关联的进程:lsof -i :1712 - 或者用
ss命令,输出更简洁:ss -tulpn | grep 1712
如果输出里能看到Python进程的PID,直接杀掉它就行:
kill -9 <进程PID>
杀掉之后再运行脚本,大概率就能正常绑定端口了。
然后,优化代码避免崩溃后残留socket连接
你的脚本目前没有任何异常处理逻辑,如果遇到Ctrl+C中断、意外崩溃的情况,socket可能不会被正常关闭,导致端口一直处于占用状态。咱们给代码加上安全退出的逻辑,确保不管怎么退出,socket都能被正确关闭:
import socket import signal import sys # 处理Ctrl+C等中断信号,确保关闭socket后再退出 def signal_handler(sig, frame): print('正在关闭socket,准备退出...') s.close() sys.exit(0) signal.signal(signal.SIGINT, signal_handler) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 保留SO_REUSEADDR,再加上SO_REUSEPORT(部分系统需要这个参数才能彻底解决端口复用问题) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) print("Socket successfully created") port = 1712 s.bind(('', port)) print("socket binded to %s" %(port)) # put the socket into listening mode s.listen(5) print("socket is listening") try: # a forever loop until we interrupt it or an error occurs while True: # Establish connection with client. c, addr = s.accept() print ('Got connection from', addr ) try: while True: data = c.recv(1024) if not data: break c.send('Thank you for connecting'.encode()) finally: # 确保客户端连接一定会被关闭 c.close() except Exception as e: print(f"运行时出现错误: {e}") finally: # 确保主socket一定会被关闭 s.close()
这段代码加了信号处理和try-finally块,不管是正常退出还是意外崩溃,都会把socket关闭,减少端口残留的概率。
最后,聊聊TIME_WAIT状态的问题
如果进程已经完全退出,但还是提示地址被占用,那大概率是端口处于TIME_WAIT状态(TCP协议用来确保数据传输完整的机制,默认会持续2分钟左右)。这时候SO_REUSEADDR应该允许你重新绑定,但有些系统可能需要额外调整参数:
你可以临时开启TCP端口重用:
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
这个命令会让系统允许重用处于TIME_WAIT状态的端口,不过不建议长期修改这个参数,除非你确定你的业务场景需要。如果不想改参数,也可以等个2分钟,端口会自动释放。
按照上面的步骤来,应该就能解决你的问题了!
备注:内容来源于stack exchange,提问作者Peter_Brown_USA
相关产品推荐
相关产品推荐

