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

如何修复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()

关键修改点说明

  1. 彻底移除原生socket的使用,改用asyncio提供的asyncio.open_connection()——这是异步环境下建立TCP连接的标准方式,自动处理连接的异步等待过程。
  2. 连接成功后通过writer.get_extra_info('sockname')获取本地地址,此时socket已经完成绑定,不会再触发无效参数错误。
  3. 修复recv()方法的无效逻辑,改用await self.reader.read(buf_size)实现真正的异步读取。
  4. 完善close_conn()方法,添加await self.writer.wait_closed()确保连接完全关闭。
  5. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:06:14