← index #2948Issue #2947
Related · high · value 2.727
QUERY · ISSUE

esp8266: socket blocking settings are inherited by accept() when they probably shouldn't be

openby dpgeorgeopened 2017-03-10updated 2024-08-28
port-esp8266

Test code:

import time, socket
s = socket.socket()
s.bind(socket.getaddrinfo("0.0.0.0", 8000)[0][-1])
s.setblocking(False)
s.listen(1)
while True:
    try:
        s2, _ = s.accept()
        break
    except OSError as er: 
        print(repr(er))
    time.sleep(1)
print('connection')
s2.recv(10)

On CPy and uPy unix, running the above code and connecting to the socket will block indefinitely at the last line, because the accepted socket s2 defaults to blocking mode.

On esp8266 the accepted socket s2 inherits the non-blocking behaviour from s.

CANDIDATE · ISSUE

esp8266: in non-blocking mode, socket.accept raises ETIMEDOUT instead of EAGAIN

closedby dpgeorgeopened 2017-03-10updated 2017-06-21
bug

Test code:

import socket
s = socket.socket()
s.bind(socket.getaddrinfo("0.0.0.0", 8000)[0][-1])
s.setblocking(False)
s.listen(1)
s.accept()

On CPy and uPy unix the accept raises EAGAIN. On esp8266 it raises ETIMEDOUT.

Note that if the socket is in a blocking mode with a finite timeout (eg s.settimeout(1)) then ETIMEDOUT is the correct error code to raise (matches CPy's socket.timeout exception for this case).

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied