micropython / micropython/micropython

Socket gets stuck while sending data on esp8266

Open
#9,570 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug port-esp8266
Dominant language
C
Stars
22.1k
Forks
9k
Avg merge
6d 4h
Merged PRs (30d)
16

Description

Hi!

I originally noticed this issue while using WebREPL. I was running loops printing sensor values and after a while (few minutes) it got stuck. It was not just one time - it reproduced over and over. So, in order to find the issue, I tried to create minimal examples using sockets and the issue reproduced for them as well. If you run following examples below for few minutes (usually 2-3), they will hang (or at least for me they do). Sometimes they hang for several seconds (upto 30) and then continue, but afterwards they hang completely. If I use non-blocking sockets it raises EAGAIN error on server. The issue occurs for both sync and async server versions.

Also I thought that maybe my wifi is unstable, but I rewrote same example on C++ (Arduino IDE) and it worked perfectly for long time without any delays and freezes.

server_async.py (run on esp)

import uasyncio

port = 3000

async def server(reader, writer):
  cnt = 0
  while True:
    print(cnt)
    await writer.awrite(f'{cnt}\n')
    cnt += 1
    await uasyncio.sleep_ms(100)
  await writer.aclose()

loop = uasyncio.get_event_loop()
loop.create_task(uasyncio.start_server(server, "0.0.0.0", port))
loop.run_forever()
loop.close()

or
server_sync.py (run on esp)

import time
import socket

port = 3000

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

ai = socket.getaddrinfo("0.0.0.0", port)
addr = ai[0][4]

server.bind(addr)
server.listen(1)

while True:
  client, remote_addr = server.accept()
  client.setblocking(False)
  cnt = 0

  while True:
    print(cnt)
    client.sendall(f'{cnt}\n')
    time.sleep_ms(100)
    cnt += 1

server.close()

client.py (run on PC)

import time
import socket

host = '...'
port = 3000

socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((host, port))

response = ''
prev = time.time()
while True:
    recv = socket.recv(1024)
    print('duration:', int((time.time() - prev) * 1000), 'ms')
    print(recv.decode(), end='')
    prev = time.time()

socket.close()

Version: MicroPython v1.19.1 on 2022-06-18; ESP module with ESP8266
Firmware: esp8266-20220618-v1.19.1.bin

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the hang with server_async.py or server_sync.py on the ESP8266 and client.py on a PC, using the stated MicroPython v1.19.1 firmware context. Compare blocking and non-blocking behavior, including the reported EAGAIN result; done means sustained sending no longer freezes or stalls in the supplied examples.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
embedded-iot, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.