esp8266: socket accept() does not always accept
If there is a queue of sockets to accept, accept() does not always clear it, some sockets seem to get "lost", they are still open but accept() will not accept them, it just blocks.
Steps to reproduce
I'm attaching two programs - main.py and client.py. Run client.py on a connected system, under normal python3. Run main.py on an esp8266. Supply the address of the esp8266 as a command line parameter.
Expected results
Despite the sleep(0.25), the sockets should queued and be accepted eventually.
Output should be, for example:
Socks connected: 4
b'Accept 0'
b'Accept 1'
b'Accept 2'
b'Accept 3'
And running the program >1 time should also succeed.
Actual results:
Socks connected: 4
b'Accept 0'
b'Accept 1'
b''
b''
lwip: socket.accept() issue on esp8266 not allowing backlog
Hi;
I spent several days trying to figure out why my simple web server is unable to serve more than 3 or 4 pages on the esp8266, and eventually I tested identical code on the esp32, and the problem disappeared, which led me to conclude that there is likely an issue with the accept() on the esp8266 and it the problem is not caused by my code.
I have created a cutdown version of my web server to demonstrate this issue, please note however that in order to make it minimal there are no try/except routines to catch bad data that may be sent by the browser.
https://github.com/pacmac/micropython-share/tree/master/www
In order to see the issue, just copy the files to your esp8266 including the htm folder and it's contents and then run the web server:
import wwwtest
wwwtest.WWW().serve()
And when the device is connected to your wlan, open up your web browser to the device IP address i.e.:
http://192.168.0.100/
The index.htm (home page) attempts to load 5 style sheets, red.css, orange.css, yellow.css, green.css and blue.css, and as you no doubt know, browsers will open multiple connections for each included files until the server refuses further connections and it will then wait for a connection to become available.
If all files get loaded successfully by the browser, then the page should display all 5 colours, when I test it on the esp8266, I only ever get maximum 3 colours and the web server logs only never show all attempted browser connections, even though the server made 6 requests, one for the index.htm page and one for each style sheet.
In order to test this correctly, you must reload the page and not use back (history) button to prevent the browser from caching the pages either in memory or disk.
As far as I understand, the socket should queue up the request, but it appears that not all of the requests are reaching the socket.accept() and the esp8266 socket appears to be dropping the connections instead of queuing them resulting in the browser 'giving up'.
If you access the developer tools window in Chrome, Firefox or Safari, when the device is the 8266, and the page is refreshed, the browser console reports:
net::ERR_CONNECTION_RESET
However on the esp32 this error is never shown and all of the pages are loaded every time, and this problem does not exist.
It does in fact appear like not all requests are reaching accept() and that the esp8266 socket only accepts up to 3 connections and then drops the rest instead of queueing them ?
Changing the queue size in socket.listen() from 1 - 5 appears to have no effect on this issue and something seems to be hard-wired at 3 connections.
Just to reiterate, identical code running on the esp32 does not exhibit this problem.