如何修复Raspberry Pi上asyncio客户端报[WinError 10022]无效参数错误?
解决OSError: [WinError 10022] 无效参数的问题
咱们先拆解下你遇到这个错误的核心原因:
- 未连接的socket调用
getsockname():创建socket后还没完成连接时,socket并没有绑定到本地的地址和端口,此时调用self.s.getsockname()必然会抛出无效参数的错误。 - 混用原生socket与asyncio异步逻辑:你给socket设置了
setblocking(False),却又直接调用同步的connect()方法——非阻塞模式下的connect会立即返回错误,而且完全没有利用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) # 连接成功后再获取本地绑定地址,此时socket已完成绑定 local_addr = self.writer.get_extra_info('sockname') print(f"Connecting as {local_addr}") async def recv(self, buf_size): # 异步读取数据,替换原来无效的占位逻辑 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(f"Closed connection with server") 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()
关键修改点说明
- 彻底移除原生socket的使用,改用asyncio提供的
asyncio.open_connection()——这是异步环境下建立TCP连接的标准方式,自动处理连接的异步等待过程。 - 连接成功后通过
writer.get_extra_info('sockname')获取本地地址,此时socket已经完成绑定,不会再触发无效参数错误。 - 修复
recv()方法的无效逻辑,改用await self.reader.read(buf_size)实现真正的异步读取。 - 完善
close_conn()方法,添加await self.writer.wait_closed()确保连接完全关闭。 send_bytes()方法增加await self.writer.drain(),保证缓冲区数据发送完成,避免异步环境下的数据丢失。
客户端代码(client.py)无需大幅修改
from aserver import Client import asyncio client = Client() async def client_run(): await client.connect(("192.168.0.11", 56500)) await client.send_bytes(b'Hi Echo Server!') await client.recv(1024) await client.close_conn() asyncio.run(client_run())
另外提个小细节:你的server.py里初始化Server时用了列表["192.168.0.11", 56500],改成元组("192.168.0.11", 56500)会更符合Python网络编程的规范,不过不影响运行。
内容的提问来源于stack exchange,提问作者codernaut1
相关产品推荐
相关产品推荐

