You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 15:51:01