Micropython asyncio StreamWriter仅发送部分数据问题求助
问题分析与修复方案
你的异步实现存在几个关键问题,导致客户端无法完整接收数据:
1. 阻塞事件循环的同步sleep
在startAccessPoint等待AP激活的循环中,使用time.sleep(1)会阻塞整个asyncio事件循环,使得服务器无法及时处理客户端连接和数据发送任务,进而导致数据传输不完整。
2. 字符串未转字节流
MicroPython的StreamWriter.write()要求传入字节对象,而非字符串。非异步的socket.send()会隐式完成字符串转字节的操作,但异步API需要显式编码。
3. Writer未正确关闭
非异步代码发送数据后直接关闭连接,但异步代码中仅调用await writer.wait_closed(),未先主动关闭writer,导致连接无法正常终止,缓冲数据可能未完全刷新到客户端。
4. 请求读取不完整
仅用await reader.readline()无法保证读完客户端的全部请求数据,残留的未读数据会阻塞socket,影响后续数据的正常发送。
修改后的完整代码
修复后的startAccessPoint函数
async def startAccessPoint(self, password): # 启动异步服务器并加入任务队列 asyncio.create_task(asyncio.start_server(self.handleClient, host="0.0.0.0", port=80)) accessPoint = network.WLAN(network.AP_IF) accessPoint.config(essid=SSID, password=password) accessPoint.active(True) timeout = 10 while timeout > 0: if accessPoint.active(): break timeout -= 1 await asyncio.sleep(1) # 替换time.sleep,避免阻塞事件循环 if not accessPoint.active(): print("Unable to start access point") return networkInfo = accessPoint.ifconfig() print("IP address: ", networkInfo[0]) while True: await asyncio.sleep(5) print("AP doing stuff")
修复后的handleClient函数
async def handleClient(self, reader: StreamReader, writer: StreamWriter): # 读取所有请求数据,避免残留数据阻塞连接 while not reader.at_eof(): await reader.read(1024) if self.stuffToSave: jsonData = self.stuffToSave.jsonData() # 修正原代码遗漏的self引用 # 将JSON字符串编码为UTF-8字节流写入 writer.write(jsonData.encode('utf-8')) await writer.drain() # 确保所有缓冲数据已发送至socket writer.close() # 主动关闭writer await writer.wait_closed() # 等待连接完全终止
额外说明
- 原代码中
jsonData = stuffToSave.jsonData()遗漏了self.,会触发变量未定义错误,已在修复代码中修正。 await writer.drain()必须调用,它会等待所有缓冲数据被发送出去,避免数据丢失。- 读取全部请求数据是为了确保socket处于可写状态,避免因未读数据导致的发送阻塞。
内容的提问来源于stack exchange,提问作者SomaMan
相关产品推荐
相关产品推荐

