-
Notifications
You must be signed in to change notification settings - Fork 13.3k
WiFiClient.connected() returns false while data are still available in receive buffer #6701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
No, they shouldn't. Connected means connected, not data available. Data availability is obtained from available() method. The logic in your loop is flawed. You read one byte, then check connection, and bail out if the connection is gone. You aren't taking into account buffering, which means that the server could be done sending and close the connection, but on your end you're not yet done receiving the buffered bytes from the client. There were bugs prior to 2.4.2 in the socket logic inside WiFiClient, where some cases of the TCP logic flow were not handled. It caused anything from stuck forever reading to dropped bytes to lost acks. The buggy behavior was made worse due to Frankenstein logic in user code. The current behavior of WiFiClient is on purpose and the product of extensive work done by @d-a-v and reviewed by me, as a result of a long number of reported issues. The ssl client was implemented by @earlephilhower on top of the normal client. Due to encryption, there was a concession made there, but the same logic applies as for WiFiClient. There are examples that show how what you're trying to do should be done, showcasing the code logic to use. Closing due to on purpose. |
https://www.arduino.cc/en/Reference/WiFiClientConnected
all other libraries have it like this
the logic of the MCVE is to show the error |
Correct, and the reference is wrong. One case is: the other side dropped the connection, there is still data available => connected() would return true. You want to send something, check that connected() is true, and write to the client => fails. So Issues would get opened again and again: writing to client fails despite connected() true. |
there is always and it doesn't match the reference |
A bit of history: Here is the documentation: esp8266 must have been more heavily using networking after Arduino made up this API (what were the network chips at that time, beside the Arduino's official Ethernet shield and library?) What @devyte says is right:
Also,
Please elaborate if anything is still not clear or documentation must be improved. |
I meant WiFiClient.status(), not WiFi.status(). It is not required by the base class Client, but all libraries have it. Arduino had WiFi and WiFi101 library in the time ESP8266WiFi library was created based on the Arduino WiFi library. The ESP8266WiFi complied to the API as it is defined for the |
@JAndrassy once again:
|
the secure Clients of the ESP8266WiFi library return true from connected() if the underlying TCP connection was closed but data are available. and the reason is same as it always was for the ESP8266WiFi has from the beginning some different function results as the Arduino Ethernet or WiFi library, but this one |
there are 3 reasons to revert it back
for TCP state WiFiClient.status() should be used |
If it is reverted, there is no way to know when peer has closed the connection. I think the I don't understand what you mean about WiFiClient.status(), can you elaborate ? And it is true WiFiClientSecureBearSSL does not follow WiFiClient. |
|
See this issue where the changes in behavior for wificlient.connected() is discussed: esp8266/Arduino#6701 A change dating back to April 2018 ( esp8266/Arduino#4626 ) does have some implications on how to interpret the client.connected() result. It is very well possible there is still data in the buffers waiting to be read. So the loop() function of pubsubclient should first try to empty the received data and then decide what to do with the connected state. So reading is fine, if there is data available, but writing needs an extra check.
ref. the original PR and the discussion esp8266#4626 esp8266#6701
Basic Infos
Platform
Settings in IDE
Problem Description
WiFiClient.connected() and WiFiClient bool() operator should return true while data are available in receive buffer. Commit b08d282#diff-a5fd274181d082a3211a59cb42a7e0d8 released in 2.4.2 changed this.
The SSL Clients have it right.
MCVE Sketch
Debug Messages
the HTTP response is cut, because immediately after last TCP packet the TCP connection is closed by HTTP server and connected() returns false
The text was updated successfully, but these errors were encountered: