Skip to content
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

Problem in NetworkClient::connected() #10559

Open
1 task done
NPaolini opened this issue Nov 3, 2024 · 5 comments
Open
1 task done

Problem in NetworkClient::connected() #10559

NPaolini opened this issue Nov 3, 2024 · 5 comments
Assignees
Labels
Status: Awaiting triage Issue is waiting for triage

Comments

@NPaolini
Copy link

NPaolini commented Nov 3, 2024

Board

ESP32

Device Description

DOIT ESP32 DEVKIT V1

Hardware Configuration

almost all GPIO are connected

Version

v3.0.5

IDE Name

Arduino IDE

Operating System

Windows

Flash frequency

80 MHz

PSRAM enabled

no

Upload speed

921600

Description

With recv() in MSG_DONTWAIT the errno is not reset when recv() returns zero, not because the connection is terminated, but because there is no data. My solution is to reset errno before call to recv(). The full explanation is in 'https://forum.arduino.cc/t/errore-nel-file-appdata-local-arduino15-packages-esp32-hardware-esp32-3-0-x-libraries-network-src-networkclient-cpp/1317872/3'

Sketch

any web server

Debug Message

remote connection closed

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@NPaolini NPaolini added the Status: Awaiting triage Issue is waiting for triage label Nov 3, 2024
@NPaolini
Copy link
Author

NPaolini commented Nov 3, 2024

Ops ... Version v3.0.7

@NPaolini
Copy link
Author

NPaolini commented Nov 6, 2024

https://www.ennepisoft.it/test_esp32/test_esp32.php
there is the project that demonstrates the reported problem, the usage information in the 'readme.txt' file (sorry, it's in Italian)

@NPaolini
Copy link
Author

NPaolini commented Nov 8, 2024

hi, this is a more 'elegant' solution to the problem. It is likely that the cause comes from using an SD card to read the site files from which could set errno to some error code. If the link (.php) to the site is a problem, I put the link directly to the zipped test_file

@NPaolini
Copy link
Author

NPaolini commented Nov 8, 2024

uint8_t NetworkClient::connected() {
  if (fd() == -1 && _connected) {
    stop();
  }
  if (_connected) {
    uint8_t dummy;
//#define RESET_ERRNO
#ifdef RESET_ERRNO
    errno = ENOENT; // <= aggiunto
    int res = recv(fd(), &dummy, 0, MSG_DONTWAIT);
    if(res > 0)
      Serial.printf("recv return %d byte\n", res);
#else
    int res = recv(fd(), &dummy, 1, MSG_DONTWAIT | MSG_PEEK);
#endif
    // avoid unused var warning by gcc
    (void)res;
    // recv only sets errno if res is <= 0
    if (res <= 0) {
      switch (errno) {
        case EWOULDBLOCK:
        case ENOENT:  //caused by vfs
          _connected = true;
          break;
        case ENOTCONN:
        case EPIPE:
        case ECONNRESET:
        case ECONNREFUSED:
        case ECONNABORTED:
          _connected = false;
          log_d("Disconnected: RES: %d, ERR: %d", res, errno);
          break;
        default:
          log_i("Unexpected: RES: %d, ERR: %d", res, errno);
          _connected = true;
          break;
      }
    } else {
      _connected = true;
    }
  }
  return _connected;
}

@NPaolini
Copy link
Author

NPaolini commented Nov 11, 2024

I compared the WebServer library with the 'cotestatnt' library and I saw that the main difference of the handleClient() (in web_server.cpp) is the presence, in the core, of the following piece of code:

            if (_currentClient.isSSE()) {
              _currentStatus = HC_WAIT_CLOSE;
              _statusChange = millis();
              keepCurrentClient = true;
            }

I commented it and it didn't give that problem anymore, but if that code exists it has its reason and I think the solution I proposed is more valid.
I wanted to try the 'ESP_Async_WebServer' (I think it's yours) and I couldn't get it to work.
If it has to load a few files or in any case small in size it's ok (e.g. the login page), but when it passes to the index it gets stuck in write().
Even if it's not the fault of this code that takes care of the transfer, I'm posting it for completeness:

//---------------------------------------
char g_Buff2[1024 * 4];
#define chunk g_Buff2
#define sizeChunk (sizeof(chunk))
//---------------------------------------
template<typename T> void loadAndsendFile(AsyncWebServerRequest* request, T filename, int mime) 
{
  DEBUG_WEB(Serial.printf("FileToSend:%s, mime:%s\n", filename, getContentType(mime)))
  if (!openFile(filename)) {
    handle404(request);
    return;
    }
  int32_t _dim = myFile.size();
  AsyncClient* client = request->client();
  DEBUG_WEB(Serial.printf("Client %s, dim:%d\n", (client ? "Ok" : "Err"), _dim))
  sendHeader(client, mime, _dim, (eHTML == mime) ? no_cache : ok_cache);
  int32_t dim = _dim;
  int fail = 0;
  while(dim > 0 && fail < 5) {
    int len = min((unsigned int)dim, sizeChunk);
    len = myFile.read((uint8_t*)chunk, len);
    if (!len)
      break;
    bool inside = dim > sizeChunk;
    const char* t = (const char*)chunk;
    fail = 0;
    do {
      // non cambia nulla tra i due
//      int sent = client->write(t, len);
      int sent = client->write(t, len, inside ? ASYNC_WRITE_FLAG_MORE : 0);
      DEBUG_WEB(Serial.printf("Dim =%d, Remain=%d, Len=%d, Sent=%d\n", _dim, dim, len, sent))
      dim -= sent;
      if(sent == len)
        break;
      t += sent;
      len -= sent;
      vTaskDelay(10);
      if(!sent)
        ++fail;
      } while(fail < 5);
    }   
  DEBUG_WEB(if(dim) Serial.println(" Failed "); else Serial.println(" Done "))
  myFile.close();
}
//-------------------------------------------------------------------

I prepared a couple of logs, one when it tries to load the index, the other directly putting the name of a fairly large image.
The direct links (without even zipping them) are:
log_site.txt
only_big_file.txt

What could it depend on?

If you want (and you are interested) I can prepare the whole folder or you can use the one already linked and I will add only the modified files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Awaiting triage Issue is waiting for triage
Projects
None yet
Development

No branches or pull requests

2 participants