Skip to content

Simultaneous wifi send & receive stalling #3011

Closed
@b3nn0

Description

@b3nn0

Basic Infos

Hardware

Hardware: ESP-12 (NodeMCU)
Core Version: Tested 2.3.0 and Git

Description

I'm trying to implement a simple HTTP Proxy server on my NodeMCU. And it already works fine for very small transfers of only a few kb. However, when transferring larger files over the Proxy, the connection will only transmit the first few kb and will then stall forever in a WiFiclient.write operation.
I also tried several combinations of setNoDelay, delay() calls, yield() calls, etc. All to no avail.
I feel like if I put in a few delay() calls, the connection works a bit longer, but I've not measured it.

Terminology:
Let "server" be the server that hosts a website,
let "client" be a browser that tries to contact the "server" via the NodeMCU proxy.

The code during a file download basically comes down to

void loop() {
  size_t len = serverConn.read(buff, 1460*2);
  if (len > 0)
    clientConn.write(buff, len);
}

The rest of the code is just connection handling, etc.
At some point, serverConn.read() will return that it has read some data, but clientConn.write() will hang forever.
If the data does not come from the server, but is generated on the device (e.g. sending megabytes of '\0' arrays), transmission rate is around 1Mb/s and stable. If the data is not forwarded to the client, but simply discarded, it's also around 1Mb/s and stable.

My uneducated guess would be, that, since the server keeps sending data as fast as possible, the internal rx buffer of the ESP will become full.
clientConn.write() will wait for an ACK, but will never be able to receive it, since the buffer is already full with data from the server. No idea if that makes sense or not, it just sounded plausible.
I also checked wireshark on the client side, and it seems that the ESP tries to retransmit multiple times and ignores the ACKs from the client, which also supports my guess.

Settings in IDE

Module: NodeMCU 1.0
Flash Size: 4MB
CPU Frequency: 80Mhz
Flash Mode: ?
Flash Frequency: ?
Upload Using: SERIAL
Reset Method: nodemcu

Sketch

The complete sketch for local testing can be found here:
https://paste.ubuntu.com/24095234/
There are also the two functions dlPage() and servePage() I used to test the general throughput of the device.

Debug Messages

Connected to: xxx, IP address: 192.168.1.17
New connection from proxy client
Read host header: GET http://example.com/large/file.zip HTTP/1.1
Connecting to host: example.com, Port: 80
Reading from browser
Read 59 bytes
Wrote bytes to http client
Done something! - Bytes written: 59
Reading from server
Read 2920 bytes from http server
Sent 2920 to proxy client
Done something! - Bytes written: 5840
Reading from server
Read 2920 bytes from http server
Sent 2920 to proxy client
Done something! - Bytes written: 5840
Reading from server
Read 2920 bytes from http server
Sent 2920 to proxy client
Done something! - Bytes written: 5840
...
Reading from server
Read 2920 bytes from http server
Sent 2920 to proxy client
Done something! - Bytes written: 5840
Reading from server
Read 2920 bytes from http server

Note that it does not always hang after the same amount of bytes. Sometimes it transmits only 5kb, sometimes 260kb or anything in between (only rarely more than that).

Tested with curl:
http_proxy=http://192.168.1.17:8080 curl http://example.com/large/file.zip > /dev/null

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions