Как я могу исправить, чтобы мой сервер asyncio не возвращал [Win 10022]?

#python #python-3.x #sockets #python-asyncio

#python #python-3.x #сокеты #python-asyncio

Вопрос:

Я писал код для сервера asyncio на моем Raspberry pi 4. Когда я кодировал клиента и выполнял тестовый запуск с моим серверным классом, он возвращает:

 Traceback (most recent call last):
  File "C:Users####Documentsrpiswrclient.py", line 23, in <module>
    asyncio.run(client_run())
  File "C:Users####AppDataLocalProgramsPythonPython39libasynciorunners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:Users####AppDataLocalProgramsPythonPython39libasynciobase_events.py", line 642, in run_until_complete
    return future.result()
  File "C:Users####Documentsrpiswrclient.py", line 18, in client_run
    await client.connect(("192.168.0.11", 56500))
  File "C:Users####Documentsrpiswraserver__init__.py", line 11, in connect
    print(f"Connecting as {self.s.getsockname()}")
OSError: [WinError 10022] An invalid argument was supplied
 

Я просмотрел ошибку, и существенного результата нет. Вот почему я спрашиваю об этом. Я перечислю свой код ниже:

init.py (в каталоге aserver):

 import asyncio, socket

class Client:
    def __init__(self):
        pass

    async def connect(self, addr):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.s.setblocking(False)

        print(f"Connecting as {self.s.getsockname()}")

        self.s.connect(addr)

    async def recv(self,buf_size):
        data = buf_size
        print(f"Recieved {data.decode()} in byte data")

    async def close_conn(self):
        print(f"Closed connection with server")

        self.s.close()

    async def send_bytes(self, data:bytes):
        self.s.sendall(data)

        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():
    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 (работает отлично):

 import aserver as srv
from aserver import Server
import asyncio

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"Recieved {message} from addr")

    print(f"Echoing {message} back")
    writer.write(data)
    await writer.drain()

    print(f"Closing connection with {addr}")
    writer.close()

asyncio.run(server.start_server(echo_server))
 

Почему возникает эта ошибка? Как мне это исправить? Любой ответ будет оценен по достоинству. Я был бы рад, если бы вы могли исправить мой код там, где вы видите проблему.

Редактировать:

Ответил @user4815162342, но спасибо всем, кто внес свой вклад!

Комментарии:

1. Ваш клиентский код по-прежнему неверен в том смысле, что он использует блокирующий код внутри async def , который может и будет блокировать весь цикл событий.

2. @user4815162342 Извините, но я действительно не понимаю, как остановить блокировку. Есть ли шанс, что я мог бы получить пример того, как прекратить блокировать цикл событий?

3. Как я уже говорил вам в предыдущем вопросе, вы можете использовать asyncio.open_connection вместо необработанных сокетов. С блокирующими сокетами вы получите код, который просто выглядит асинхронным, но не использует асинхронные вызовы под капотом и, следовательно, не получает никаких преимуществ от asyncio.