如何修复Raspberry Pi 4上asyncio客户端报[Win 10022]错误?
错误原因及修复方案
让我来帮你分析这个错误并修复代码:
核心错误原因
你遇到的OSError: [WinError 10022] An invalid argument was supplied是由两个关键问题导致的:
- 未连接的非阻塞Socket调用
getsockname():你在Socket还未完成连接时就调用getsockname(),此时Socket还没有绑定到本地地址,系统无法返回有效信息,因此抛出无效参数错误。 - 混用同步Socket和asyncio异步模型:直接调用
self.s.connect(addr)在非阻塞模式下会立刻抛出BlockingIOError,因为非阻塞Socket不会等待连接完成,而你没有用asyncio的机制来处理异步连接流程,完全违背了asyncio的异步编程逻辑。
修复后的完整代码
aserver/init.py
import asyncio class Client: def __init__(self): self.reader = None self.writer = None async def connect(self, addr): # 使用asyncio官方推荐的流API建立异步连接 self.reader, self.writer = await asyncio.open_connection(addr[0], addr[1]) # 连接建立后再获取本地地址,此时是安全有效的 local_addr = self.writer.get_extra_info('sockname') print(f"Connecting as {local_addr}") async def recv(self, buf_size): # 异步读取数据,符合asyncio模型 data = await self.reader.read(buf_size) if data: print(f"Received {data.decode()} in byte data") return data async def close_conn(self): print("Closed connection with server") if self.writer: self.writer.close() await self.writer.wait_closed() # 等待连接完全关闭,避免资源泄漏 async def send_bytes(self, data: bytes): self.writer.write(data) await self.writer.drain() # 异步等待数据发送完成 print(f"Sent {data.decode()} in byte format") class Server: """Implement handle function or decorate a function with @Server.handler(<Server>)""" def __init__(self, addr): self.addr = addr async def start_server(self, handler_method): self.server = await asyncio.start_server(handler_method, self.addr[0], self.addr[1]) self.addr = self.server.sockets[0].getsockname() print(f"Serving on {self.addr}") async with self.server: await self.server.serve_forever()
client.py
from aserver import Client import asyncio client = Client() async def client_run(): try: await client.connect(("192.168.0.11", 56500)) await client.send_bytes(b'Hi Echo Server!') await client.recv(1024) finally: # 确保无论是否出错,连接都会被关闭 await client.close_conn() asyncio.run(client_run())
server.py(优化细节)
import aserver as srv import asyncio # 将地址从列表改为元组,符合Socket API的标准格式 server = srv.Server(("192.168.0.11", 56500)) async def echo_server(reader, writer): data = await reader.read(1024) message = data.decode() addr = writer.get_extra_info('peername') print(f"Received {message} from {addr}") print(f"Echoing {message} back") writer.write(data) await writer.drain() print(f"Closing connection with {addr}") writer.close() await writer.wait_closed() # 新增:等待连接彻底关闭 asyncio.run(server.start_server(echo_server))
关键优化点说明
- 抛弃原生Socket直接使用asyncio流API:
asyncio.open_connection和asyncio.start_server是官方推荐的异步网络编程方式,自动处理事件循环和异步IO,避免手动操作Socket的复杂度和错误。 - 确保资源安全释放:客户端用
finally块保证连接关闭,服务器端新增await writer.wait_closed()确保连接彻底释放,避免资源泄漏。 - 修正地址类型:将服务器初始化的地址从列表改为元组,符合Socket API的标准参数格式。
内容的提问来源于stack exchange,提问作者codernaut1
相关产品推荐
相关产品推荐

