uasyncio.start_server leades OSError: [Errno 107] ENOTCONN
I ported miccropython on stm32. And intend to use uasyncio to open the server. However, the system reports an error like
Task exception wasn't retrieved
future: <Task> coro= <generator object 'start_server' at 20005aa0>
Traceback (most recent call last):
File "uasyncio/core.py", line 176, in run_until_complete
File "uasyncio/stream.py", line 155, in start_server
OSError: [Errno 107] ENOTCONN
MicroPython v1.19.1-dirty on 2023-07-04; XREG09E0103 with STM32F405RG
Type "help()" for more information.
After looking up, I found that it was caused by the error here
s.setblocking(False)
this is my complete code
import uasyncio as asyncio
import network
import time
import machine, pyb
nic = network.WIZNET5K(machine.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y1)
W5500_RST = pyb.Pin('Y1', pyb.Pin.OUT_PP)
W5500_RST.low()
time.sleep_ms(10)
W5500_RST.high()
time.sleep(1)
print(0)
nic.ifconfig(('192.168.0.100', '255.255.255.0', '192.168.0.12', '8.8.8.8'))
print(1)
print(nic.ifconfig())
while nic.ifconfig()[0] == '0.0.0.0':
time.sleep_ms(100)
nic.isconnected()
print(nic.isconnected())
while nic.isconnected() == False:
time.sleep_ms(100)
print('RJ45 Connected ERROR')
print('RJ45 Connected OK')
sem = asyncio.Semaphore(1)
async def handle_echo(reader, writer):
# data = await reader.read(100)
# while True:
data = await reader.readline()
print(data)
# message = data.decode()
# print("Received %r" % message)
addr = writer.get_extra_info('peername')
print("Received %r from %r" % (data, addr))
# print("Send: %r" % message)
# writer.write(data)
# await writer.drain()
# print("Close the client socket")
# writer.close()
loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, '127.0.0.1', 8888, backlog=5)
server = loop.run_until_complete(coro)
loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, '192.168.0.100', 8888, backlog=5)
loop.create_task(coro)
try:
print("1")
loop.run_forever()
except KeyboardInterrupt:
print("closing")
loop.close()
Has anyone ever encountered a similar situation? How did everyone solve it?
extmod/uasyncio: Get addr and bind server socket before creating task.
Currently when using uasyncio.start_server() the socket configuration is
done inside a uasyncio.create_task() background function. If the address
and port are already in use however this throws an OSError which cannot be
cleanly caught behind the create_task().
This commit moves the getaddrinfo and socket binding to the start_server()
function, and only creates the task if that succeeds. This means that any
OSError from the initial socket configuration is propagated directly up the
call stack, compatible with CPython behaviour.
This is an alternative to #7444.