Thanks to visit codestin.com
Credit goes to github.com

Skip to content

WiFiClient.connected() broken (won't react to FIN / shutdown() from other side) #1527

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

Closed
brainsucker-na opened this issue Jun 23, 2018 · 4 comments
Labels
Status: Stale Issue is stale stage (outdated/stuck)

Comments

@brainsucker-na
Copy link

Description:

WiFiClient.connected() is broken since merging of #1388
connected() won't change to false even when with no data in receive buffer and FIN packet received (indication from other side no more data is incomming, normally via shutdown(SHUT_WR) call).

So any simple code like this won't work properly for now (well, unless TCP will timeout sooner or later):

while (client.connected()) 
          if (client.available() > 0)
            client.readBytes(buf, min(256, client.available()));

Please find the minimal sketch below, connect to your esp32 with telnet ("telnet 192.168.0.66 8080" for example) and close telnet window (if I kill telnet process instead of closing its window it will send RST packet and any build will behave the same). Sketch built with espressif32@~0.12.0 will drop from 'connected' cycle immediately, sketch built with current release or staging will wait for TCP timeout.

After inserting log_e into WiFiClient::connected():
espressif32@~0.12.0:

[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res -1 errno 11
[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res -1 errno 11
---Connected to client---
[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res -1 errno 11
....
[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res -1 errno 11
[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res 0 errno 128
---Client closed connection---

current release or staging:

[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res -1 errno 11
[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res -1 errno 11
---Connected to client---
[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res -1 errno 11
....
[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res -1 errno 11
[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res 0 errno 128
[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res -1 errno 11
.....
[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res -1 errno 11
[E][WiFiClient.cpp:316] connected(): wifi_connected: recv res -1 errno 104
---Client closed connection---

Error codes:
#define ECONNRESET 104 /* Connection reset by peer /
#define ENOTCONN 128 /
Socket is not connected /
#define EAGAIN 11 /
No more processes */

I did no research if recv res = 0 and error code ENOTCONN is a valid behavior on idf side, that issue might be a manifestation of bug in it.

Screenshots from wireshark (top - current release, bottom espressif32@~0.12.0, each time first connection ended by closing telnet (shutdown/FIN packet), second connection terminated (close/RST packet).

Sketch:

#include <Arduino.h>
#include <WiFi.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

WiFiServer server(8080);

void setup() {
  Serial.begin(115200);

   WiFi.mode(WIFI_STA);
   WiFi.begin("111", "111");
   while (WiFi.waitForConnectResult() != WL_CONNECTED) {
     Serial.println("Connection Failed! Rebooting...");
     delay(5000);
     ESP.restart();
   }
    Serial.print("Connected to wifi. My address:");
    IPAddress myAddress = WiFi.localIP();
    Serial.println(myAddress);

    server.begin();
}

void loop() {
    WiFiClient client = server.available();
    if (client) {
      if (client.connected()) 
        Serial.println("---Connected to client---");

      unsigned char buf[256];
      while (client.connected()) {
          if (client.available() > 0) {
            int l = client.available();
            if (l > 256)  l = 256;
            client.readBytes(buf, l);
            Serial.write(buf, l);
          } else
            delay(300);
      }
      Serial.println("---Client closed connection---");
      client.stop();
    }
}
@ryanchyshyn
Copy link

I encountered the same issue.
Here is my workaround:

if (client.status() == CLOSED)
{
	client = server.available();
}
if (client.status() != CLOSED)
{
	if (!prevConnected)
	{
		prevConnected = true;
		Serial.println("Connected");
		server.stop();
	}
	// handle read
}
else
{
	if (prevConnected)
	{
		// client disconnected. Lets free resources
		client.stop();
		prevConnected = false;
		Serial.println("Disconnected");

		server.begin();
	}
}

@avinashk15
Copy link

I could not found client.status() function .

@stale
Copy link

stale bot commented Aug 1, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the Status: Stale Issue is stale stage (outdated/stuck) label Aug 1, 2019
@stale
Copy link

stale bot commented Aug 15, 2019

This stale issue has been automatically closed. Thank you for your contributions.

@stale stale bot closed this as completed Aug 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Stale Issue is stale stage (outdated/stuck)
Projects
None yet
Development

No branches or pull requests

3 participants