Raspi Pico W设置SO_REUSEADDR仍遇[Errno 98] EADDRINUSE问题求助
解决Raspberry Pi Pico W上MicroPython的socket地址复用问题
针对你遇到的设置SO_REUSEADDR后仍出现EADDRINUSE的问题,核心原因是MicroPython的socket实现与标准CPython存在差异,结合Pico W的TCP栈特性,可以通过以下几种方式解决:
1. 调整socket选项的设置顺序与额外参数
MicroPython中,SO_REUSEADDR需要在绑定端口前设置,部分版本还需要搭配SO_REUSEPORT才能生效。另外,添加SO_LINGER选项可强制socket关闭时立即释放端口,避免TIME_WAIT状态占用:
import socket server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 先设置地址复用选项 server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 尝试设置端口复用(部分MicroPython版本支持) try: server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) except AttributeError: pass # 不支持则忽略 # 设置关闭时立即释放端口,跳过TIME_WAIT try: server_sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, (1, 0)) except AttributeError: pass # 再绑定并监听 server_sock.bind(('0.0.0.0', 1234)) server_sock.listen(1)
2. 确保socket资源被正确释放
客户端断开后,必须先关闭客户端连接的socket,再处理监听socket;异常场景下也要保证socket被关闭,避免资源泄漏:
while True: client_sock = None try: client_sock, addr = server_sock.accept() # 处理客户端请求逻辑 data = client_sock.recv(1024) if data: client_sock.sendall(data) except Exception as e: print(f"Error: {e}") finally: # 确保客户端socket被关闭 if client_sock: client_sock.close()
如果需要重启服务端(而非持续监听),则在重启前必须关闭监听socket:
# 重启前执行 server_sock.close() # 重新创建socket并设置选项、绑定
3. 升级MicroPython版本
你使用的是2022年的nightly版本,该版本的socket模块可能存在SO_REUSEADDR的实现bug。建议升级到最新的稳定版或nightly镜像,后续版本已修复了不少TCP栈相关的问题。
内容的提问来源于stack exchange,提问作者M463
相关产品推荐
相关产品推荐

