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
>>>
Non-blocking UDP socket returns ETIMEDOUT on recv instead on EAGAIN on ESP8266
When reading from non-blocking UDP socket with no data available ETIMEDOUT error is returned. One would expect EAGAIN or EWOULDBLOCK in such situation.
For example:
>>> import usocket
>>> s = usocket.socket(usocket.AF_INET, usocket.SOCK_DGRAM)
>>> address = usocket.getaddrinfo('192.168.0.24', 4005)[0][-1]
>>> s.bind(address)
>>> s.settimeout(0)
>>> s
<socket state=0 timeout=0 incoming=0 off=0>
>>> s.recv(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 110] ETIMEDOUT
The incorrect behaviour is observed for ESP8266 platform:
>>> sys.platform
'esp8266'
>>> sys.implementation
(name='micropython', version=(1, 12, 0), mpy=9733)
Looking at the modlwip.c code, there seems to be no special treatment applied for timeout value of 0:
https://github.com/micropython/micropython/blob/master/extmod/modlwip.c#L597