树莓派Pico W使用_thread库实现数据采集与Web服务器并行运行的问题
树莓派Pico W使用_thread库实现数据采集与Web服务器并行运行的问题
嘿,我来帮你排查这个问题~你的思路完全没问题,用线程分离Web服务和数据采集逻辑是正确的,但看起来是几个细节没处理好导致Web服务器“失联”了:
问题根源分析
- 未读取客户端请求数据:当浏览器向服务器发起HTTP请求时,会先发送请求头信息,如果你的服务器不读取这些数据,TCP连接会卡在半开状态,后续的响应无法正常发送,浏览器就会一直显示“无法访问”。
- 缺少标准HTTP响应头:直接发送HTML内容而不附带HTTP状态码和响应头,部分浏览器无法正确解析响应,也会导致服务异常。
- Socket选项未配置:如果socket没有设置
SO_REUSEADDR,可能会出现地址占用的问题,导致线程里的服务无法正常监听。
修改后的代码示例
首先修正serve函数:
def serve(connection): while True: client = connection.accept()[0] try: # 必须先读取客户端的请求数据,避免连接阻塞 request = client.recv(1024) # 生成网页内容 html = webpage() # 发送标准HTTP响应头 client.send('HTTP/1.1 200 OK\n') client.send('Content-Type: text/html\n') client.send('Connection: close\n\n') # 发送网页内容 client.send(html) except Exception as e: print(f"Error serving client: {e}") finally: # 确保客户端连接被关闭 client.close()
然后检查open_socket函数,确保添加地址复用选项:
def open_socket(ip): import socket address = (ip, 80) connection = socket.socket() # 允许地址复用,避免重启时出现地址占用错误 connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) connection.bind(address) connection.listen(1) print(f"Listening on {ip}:80") return connection
主线程逻辑保持不变即可:
ip = connect() connection = open_socket(ip) _thread.start_new_thread(serve, (connection,)) while True: GetSensorsValues() sleep(5)
额外说明
- MicroPython的
_thread库是抢占式调度的,主线程的sleep(5)会自动释放CPU资源给Web服务线程,不用担心阻塞问题。 - 如果你需要在网页中展示实时采集到的传感器数据,可以把传感器值存在一个全局变量里,
webpage()函数生成HTML时直接读取这个变量即可;如果涉及多线程修改全局变量,最好用_thread.allocate_lock()加个锁,避免数据混乱。
备注:内容来源于stack exchange,提问作者Romain
相关产品推荐
相关产品推荐

