micropython: Bugs and limitations of socket module
On the A9G board, with s being a Berkeley socket (import socket; s = socket.socket()) entering the following commands yields errors:
s.recv(50)when rx buffer is empty freezes the board, even after as.settimeout(3),s.connect((url, port))executed twice in a row freezes the board,- looking at
syields<socket>only.
By comparison, behaviors of those commands on an ESP8266 with the latest firmware are:
s.recv(50)when rx buffer is empty results in anOSError: [Errno 110] ETIMEDOUTerror, after having sets.settimeout(3),s.connect((url, port))executed twice yields anOSError: 106 error, and the socket remains connected,- looking at
syields<socket state=0 timeout=-1 incoming=0 off=0>which gives enhanced state of the socket (e.g., to track network errors).
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 1
- Comments: 18 (5 by maintainers)
Commits related to this issue
- Remove the workaround of #50 in favor of patched libcsdk — committed to pulkin/micropython by pulkin 4 years ago
- Remove the workaround of #50 in favor of patched libcsdk — committed to intx82/micropython_a9_gprs by pulkin 4 years ago
So I kept testing and it turns out that the problem is not the voltage or the socket.close() method.
There’s a problem with socket.recv(). After removing this from the code I was able to loop indefinetely without the module rebooting because it hangs, and the data gets correctly transmitted every time.
I do need to access the response from the server as it contains a few variables that the program inside the module uses.
I’ve read that other modules like ESP32 and ESP8266 have had this problem but they have been corrected so I don’t know why this happens with the latest version of micropython.
UPDATE:
I solved it by replacing
response=s.recv(256)withNow it loops forever without hanging 😃
The latest build produces this:
I do not know whether it is a fair result but, at least, it does not halt the module and is easy to implement.
I fixed one limiting case instead of the core problem which requires patching. Some of the underlying lwip exceptions are not written in
errno: they are, for some reason, redirected to the platform error handler which displays an error incoolwatcherand halts the module. I will try to fix it.I fixed this:
s.connectcalled twiceOSError(EISCONN)is raiseds.recvon empty socketOSError(ENOTCONN)is raised (on ESP8266 it’sOSError(0))Socket errors can be traced in cooltools. I was not able to reproduce the timeout problem: please provide a minimal working example.