W5500-EVB-PICO: setblocking, SOL_SOCKET, SO_REUSEADDR NOT working; Cannot use Asyncio start_server()
I'm currently working with the Wiznet W5500-EVB-PICO. For those who aren't familiar, it's essentially a Raspberry Pi Pico and a Wiznet Ethernet Hat combined onto a single board and, as the name implies, gives you a wired ethernet connection.
I'm currently using the following firmware: v1.0.5
Version information from the REPL:
MicroPython v1.18-10-g5db278f1d-dirty on 2022-05-10; Raspberry Pi Pico with RP2040
I'm trying to use Asyncio to start a server.
When I run this code I receive the following error(s):
Task exception wasn't retrieved
future: <Task> coro= <generator object 'start_server' at 2000d700>
Traceback (most recent call last):
File "uasyncio/core.py", line 1, in run_until_complete
File "uasyncio/stream.py", line 1, in start_server
OSError: [Errno 107] ENOTCONN
For reference, similar versions of the above code have worked on both an ESP8266 and Raspberry Pi Pico W.
The Raspberry Pi Pico W version that I've used can be found here.
Upon further inspection it seems that using the following seem to be causing issues:
- socket.setblocking(False)
- socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
To this hypothesis, I used some known-good example code for a small non-asynchronus HTTP server and added the following lines of code (one at a time) to see if I could invoke the error.
s.setblocking(False)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
With "s.setblocking(False)" uncommented on line 51, the following error occurs:
Traceback (most recent call last):
File "<stdin>", line 80, in <module>
File "<stdin>", line 51, in main
OSError: [Errno 107] ENOTCONN
With "s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)" uncommented at line 52, the following error occurs:
Traceback (most recent call last):
File "<stdin>", line 80, in <module>
File "<stdin>", line 52, in main
AttributeError: type object 'socket' has no attribute 'SOL_SOCKET'
It seems that start_server() uses both of these lines of code and, they don't seem to be compatible with the W5500 wrapper/driver that is used in this firmware.
I respectfully request that someone look into this issue. I'll provide any additional information that is required. I'm a hardware guy who recently started doing software so I'll try my best.
non-blocking socket blocks and raises EAGAIN
from https://github.com/pfalcon/micropython/issues/30
Problem: a non-blocking socket seems to block and raises EAGAIN (was EWOULDBLOCK some time ago)
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== import socket as _socket
=== ai = _socket.getaddrinfo("127.0.0.1", 85, 0, _socket.SOCK_STREAM)
=== ai = ai[0]
=== s = _socket.socket(ai[0], ai[1], ai[2])
=== s.setblocking(False)
=== s.setsockopt(_socket.SOL_SOCKET, _socket.SO_REUSEADDR, 1)
=== s.bind(ai[-1])
=== s.listen(0)
===
>>> s2, client_addr = s.accept()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 11] EAGAIN
This problem only appears, when AP mode is disabled. Connecting to a WiFi does not help.
See https://github.com/pfalcon/micropython/issues/30#issuecomment-497322149
Catching EAGAIN works but this only circumvents that bug...
paste mode; Ctrl-C to cancel, Ctrl-D to finish
=== import socket as _socket
=== ai = _socket.getaddrinfo("127.0.0.1", 85, 0, _socket.SOCK_STREAM)
=== ai = ai[0]
=== s = _socket.socket(ai[0], ai[1], ai[2])
=== s.setblocking(False)
=== s.setsockopt(_socket.SOL_SOCKET, _socket.SO_REUSEADDR, 1)
=== s.bind(ai[-1])
=== s.listen(0)
===
>>> try:
>>> s2, client_addr = s.accept()
>>> except OSError as e:
>>> if e.args[0] == uerrno.EAGAIN:
>>> continue
>>>