espressif / esp-lwip

Fork of lwIP (https://savannah.nongnu.org/projects/lwip/) with ESP-IDF specific patches
Other
79 stars 126 forks source link

TCP stack sending data in 256bytes of chunk from server but TCP client(Windows PC (Hercules.exe)) receives random size of chunk (IDFGH-8715) #49

Closed cravalgasleak closed 5 months ago

cravalgasleak commented 1 year ago

I am using ESP32C3 as TCP server. I have used stack provided by you. I also used TCP server application code which is provided by ESP example. I am using 4.4.1 version of esp-idf SDK .

When I connect PC as TCP client and send data in 256bytes of chunk from ESP32C3(TCP server) to hercule.exe(TCP client) continuously without any delay I am receiving random chunk of data in multiple of 256bytes and random chunks instead of exact 256bytes for each packets.

I have verified in wireshark.exe it shows TCP server is sending in multiple of 256bytes when issue occurred but in code I am hardcoding 256bytes every time to stream to client. If I add delay of 300ms after each packet sending to client I am getting data in 256bytes of chunk each time at client side. can somebody guide me through to understand why we require this 300ms delay and can we use TCP flags in place of delay to get exact 256bytes for each packet i stream from server?

xueyunfei998 commented 1 year ago

hi @cravalgasleak The lwip protocol stack used in idf, uses the delay ack mechanism.

Simply put, Delay Ack means sending ACK in a delayed manner. When a packet is received, it will check whether it needs to be sent. If it is necessary, it will carry out fast ACK or delayed ACK. When fast acknowledgement is not available, Delay Ack will be used.

When TCP sends ACK, there are the following rules:

  1. When response data is sent, ACK will be sent with the data.

  2. If there is no response data, there will be a delay for ACK to wait for whether there is a response data to be sent, but this delay is generally between 40ms and 500ms, usually around 40ms. If there is data to be sent within 40ms, then ACK will be sent along with the data. Attention should be paid to this delay. This delay does not mean the time delay from receiving data to sending ACK. Instead, the kernel will start a timer and check it every 200ms. For example, if the timer starts in 0ms, expires in 200ms, and data arrives in 180ms, then there is no response data in 200ms, and ACK will still be sent, which is delayed by 20ms.

So every time you send 256 bytes, wait 300ms, and the other party will receive the complete 256 bytes after the delay ack timeout.

Alvin1Zhang commented 5 months ago

Thanks for reporting, will close due to short of feedback, feel free to reopen with more updates.