Skip to content

WiFiClient issuing no Timeout using client.readStringUntil() #5304

Closed
@artua

Description

@artua

Platform

  • Hardware: [ESP-12]
  • Core Version: [8ae0746]
  • Development Env: [Arduino IDE]
  • Operating System: [MacOS]

Settings in IDE

  • Module: [Generic ESP8266 Module]
  • Flash Mode: [qio]
  • Flash Size: [4MB/1MB]
  • lwip Variant: [v2 Lower Memory]
  • Reset Method: [nodemcu]
  • Flash Frequency: [40Mhz]
  • CPU Frequency: [160MHz]
  • Upload Using: [SERIAL]
  • Upload Speed: [115200]

Problem Description

No Timeout implemented using client.readStringUntil()
Tested with WiFiClient, WiFiClientSecure, BearSSL::WiFiClientSecure

MCVE Sketch

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <WiFiClient.h>

   WiFiClient client;

const int API_TIMEOUT = 1500;
struct Result {
  int code;
  String content;
};
  Result res;
struct Timings {
  int count;
  int conn;
  int req;
  int head;
  int body;
  int stop;
  int htout;
  int btout;
};

Timings t;

String line;
int myWdt;

const char* host = "el-sag.com";
const char* url = "/wm/tout.cgi";
const int httpsPort = 80;
long init_ms;
String data = "{}";
bool TOUT;
  int c_len;
  char c_buf[512];
  int bytes;

void setup() {
init_ms = millis();
  Serial.begin(74880);
  Serial.print("Connecting to Wifi");
  WiFi.begin();
  while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(200); }
  Serial.println();
  logger("Free HEAP: " + String(ESP.getFreeHeap()));
  
}

void loop() {
  t.count++;
  myWdt = millis();

  client.setTimeout(API_TIMEOUT);
  logger("Client Secure started " + String(millis() - myWdt) + " ms");
  logger("Free HEAP: " + String(ESP.getFreeHeap()));
  logger("connecting to " + String(host));
  t.conn += millis() - myWdt;
  myWdt = millis();
  if (!client.connect(host, httpsPort)) {
    logger("Connection failed " + String(millis() - myWdt) + " ms");
    res.code = 0; res.content = F("connection failed");
    return; // 1 = connection failed
  }
  logger("Free HEAP: " + String(ESP.getFreeHeap()));
  t.conn += millis() - myWdt;
  logger("Connected " + String(millis() - myWdt) + " ms");
  myWdt = millis();
  
  logger("Free HEAP: " + String(ESP.getFreeHeap()));
  logger("requesting URL: " + String(url) + " with data: " + String(data));
  myWdt = millis();
  
  
  client.print(String("POST ") + url + " HTTP/1.0\r\n" +
               "Host: " + host + "\r\n"
               + "Content-Type: application/json\r\n"
               + "Content-Length: " + data.length() + "\r\n\r\n"
               + data);

  t.req += millis() - myWdt;
  logger("Request sent " + String(millis() - myWdt) + " ms");
  logger("Free HEAP: " + String(ESP.getFreeHeap()));
  client.setTimeout(API_TIMEOUT);
  
  myWdt = millis();
  TOUT=1;
  while (client.connected()) {
    line = client.readStringUntil('\n');
    if (line.startsWith("HTTP/1.")) {
      res.code = line.substring(9, 12).toInt();
      logger("Got HTTP code " + String(res.code));
    }
    if (line.startsWith("Content-Length: ")) {
      c_len = line.substring(15).toInt();
      logger("Got Content-length: " + String(c_len));
    }
    if (line == "\r") {
      t.head += millis() - myWdt;
      logger("Headers received " + String(millis() - myWdt) + " ms");
      logger("Free HEAP: " + String(ESP.getFreeHeap()));
      TOUT=0;
      break;
    }
  }
  if(TOUT) { 
    t.htout++;
    logger("\n*** Timeout receiving headers. Connected: " + String(client.connected()));
    return;
  }
  
  myWdt = millis();
  if (client.available()) {
    TOUT=1;
    //res.content += String(client.read());
    bytes = client.readBytes(c_buf, c_len);
    c_buf[c_len] = '\0';
    TOUT=0;
  }
  if(TOUT) { 
    t.btout++;
    logger("\n*** Timeout receiving body. Connected: " + String(client.connected()));
    return;
  }
  res.content = String(c_buf);
  logger("Result length: " + String(res.content.length()) + " | " + String(bytes));
  t.body += millis() - myWdt;
  logger("Content received " + String(millis() - myWdt) + " ms");
  logger("Free HEAP: " + String(ESP.getFreeHeap()));
  myWdt = millis();
  client.stop();
  t.stop += millis() - myWdt;
  logger("Client stop " + String(millis() - myWdt) + " ms");
  logger("Free HEAP: " + String(ESP.getFreeHeap()));
  logger("\n*** Result: " + res.content);
  logger(String("Cycles: ") + t.count + " Head TOUTs: " + t.htout + " Body TOUTs: " + t.btout + "\nConn ave: " + t.conn/t.count 
  + "\nReq ave: " + t.req/t.count + "\nHead ave: " + t.head/t.count 
  + "\nBody ave: " + t.body/t.count + "\nStop ave: " + t.stop/t.count + "\nOverall ave: " + (t.conn+t.req+t.head+t.body+t.stop)/t.count);
//  logger("Session size: " + String(sizeof(session)));
}

void printTS() {
  long ts = millis() - init_ms;
  int m = ts / 60000;
  int s = (ts) / 1000 - m * 60;
  int ms = ts - m * 60000 - s * 1000;
  Serial.printf("%02d:%02d:%03d ", m, s, ms);
}

void logger(String str) {
  printTS();
  Serial.println(str);
}

Debug Messages

SDK:3.0.0-dev(c0f7b44)/Core:2.4.2-96-g8ae0746e/lwIP:2.1.0(STABLE-2_1_0_RELEASE/glue:arduino-2.4.2-13-g80224f0)/BearSSL:f55a6ad
Connecting to Wifiscandone
.scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 4
cnt 

connected with Welcome, channel 11
dhcp client start...
.ip:192.168.3.128,mask:255.255.255.0,gw:192.168.3.200

00:00:408 Free HEAP: 49352
00:00:408 Client Secure started 0 ms
00:00:408 Free HEAP: 49352
00:00:409 connecting to el-sag.com
00:00:594 Free HEAP: 48928
00:00:595 Connected 185 ms
00:00:595 Free HEAP: 48928
00:00:595 requesting URL: /wm/tout.cgi with data: {}
00:00:597 Request sent 1 ms
00:00:600 Free HEAP: 48232
pm open,type:2 0
00:12:362 Got HTTP code 200
00:12:368 Headers received 11765 ms
00:12:368 Free HEAP: 47984
00:12:369 Result length: 0 | 0
00:12:369 Content received 0 ms
00:12:370 Free HEAP: 47984
00:12:374 Client stop 1 ms
00:12:376 Free HEAP: 48056
00:12:380 
*** Result: 
00:12:384 Cycles: 1 Head TOUTs: 0 Body TOUTs: 0
Conn ave: 186
Req ave: 1
Head ave: 11765
Body ave: 0
Stop ave: 1
Overall ave: 11953

Metadata

Metadata

Assignees

Labels

waiting for feedbackWaiting on additional info. If it's not received, the issue may be closed.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions