QUERY · ISSUE
non-blocking socket blocks and raises EAGAIN
port-esp8266
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
>>>
CANDIDATE · PULL REQUEST
unix/modusocket: Finish socket.settimeout() implementation.
unix/modusocket: Initial implementation of socket.settimeout().
unix/modusocket: Finish socket.settimeout() implementation.
1. Return correct error code for non-blocking vs timed out socket
(POSIX returns EAGAIN for both, we want ETIMEDOUT in case of timed
out socket). To achieve this, blocking/non-blocking flag is added
to the mp_obj_socket_t, to avoid issuing fcntl() syscall each time
EAGAIN occurs. (mp_obj_socket_t used to be 8 bytes, having some room
in a standard 16-byte alloc block.)
2. Handle socket.settimeout(0) properly - in Python, that means
non-blocking mode, but SO_RCVTIMEO/SO_SNDTIMEO of 0 is infinite
timeout.
3. Overall, make sure that socket.settimeout() call switches blocking
state as expected.