2

I am attempting to write a file found on an SD card to a connected Ethernet client. The file opens fine, and we have no problems writing to the client. For testing purposes I also write the lines read from the file to the serial port at the same time as being written to the client. What is happening though, is that the entire file contents are displayed in the serial monitor, but the browser only receives about 2978 characters. the actual file, not including the header, sent separately, is 4426 bytes long. I ran a test sending about 260000 via 8000 "client.print(...)" statements and this worked fine.

I have attached code. Anything not necessary to the basic function of the code has been stripped out to give us the minimum required to debug. I am using the libraries EthernetWebServer_SSL_STM32 & sdFat. My code is derived from the WebServer example.

/****************************************************************************************************************************
  WebServer.ino - Simple Arduino web server sample for ESP8266 AT-command shield
  For STM32F/L/H/G/WB/MP1 with built-in Ethernet LAN8742A (Nucleo-144, DISCOVERY, etc) or W5x00/ENC28J60 shield/module
  
  EthernetWebServer_SSL_STM32 is a library for STM32 using the Ethernet shields to run WebServer and Client with/without SSL
  Use SSLClient Library code from https://github.com/OPEnSLab-OSU/SSLClient
  
  Built by Khoi Hoang https://github.com/khoih-prog/EthernetWebServer_SSL_STM32
  Licensed under MIT license
 *****************************************************************************************************************************/
#define REPLY_HEADER    "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n"
    
    void Process_Client_Request()
    {
        FsFile      file;
        char        line[500];
        char        Received_Character = '\0';
        uint32_t    Character_Index    =   0;
        uint32_t    n;
        uint32_t    File_Length_Bytes;
        uint32_t    File_Length_Lines;
    
        // listen for incoming clients
        EthernetClient client = server.available();
        
    //  static  ArduinoOutStream sout(client);
        static  ArduinoOutStream cout(Serial);
    
        
        if (client)
        {
            // an http request ends with a blank line
            bool currentLineIsBlank = true;
            
            while (client.connected())
            {
                if (client.available())
                {
                    char c = client.read();
                    Serial.write(c);
                    // if you've gotten to the end of the line (received a newline
                    // character) and the line is blank, the http request has ended,
                    // so you can send a reply
                    if (c == '\n' && currentLineIsBlank)
                    {
                        Serial.println(F("Sending response:\n"));
                        
                        // send a standard http response header
                        // use \r\n instead of many println statements to speedup data send
                        client.print(REPLY_HEADER);
                        Serial.println(F(REPLY_HEADER));
                        
                        // Open the SD card
                        if (!sd.begin(SD_CONFIG)) 
                        {
                            sd.initErrorHalt(&Serial);
                        }
                        
                        // Specify the file to read
                        char fileName[] = "404.htm";
                        
                        // Open the file to READ from the SD card
                        if (!file.open(fileName, O_READ)) 
                        {
                            sd.errorHalt(&Serial, F("open failed"));
                        }
                        
                        File_Length_Bytes = file.fileSize();
                        File_Length_Lines = 0;
    
                        Serial.print(__DATE__); Serial.print(", "); Serial.println(__TIME__);
    
                        while ((n = file.fgets(line, sizeof(line))) > 0)
                        {
                            // Write the line to the client
                            client.print(line);
    
                            // Print the line
                            Serial.print(line);
    
                            File_Length_Lines++;
                        }
                        file.close();
                        break;
                    }
                    
                    if (c == '\n')
                    {
                        // you're starting a new line
                        currentLineIsBlank = true;
                    }
                    
                    else if (c != '\r')
                    {
                        // you've gotten a character on the current line
                        currentLineIsBlank = false;
                    }
                }
            }
            // give the web browser time to receive the data
            delay(10);
            
            // close the connection:
            client.stop();
            Serial.println(F("\n\nClient disconnected"));
            
            Serial.println("\n");
            Serial.print("Total bytes read: "); Serial.println(File_Length_Bytes);
            Serial.print("Total lines read: "); Serial.println(File_Length_Lines);
            Serial.println("");
        }   
    }

Any ideas what I am doing wrong?

I tried removing all references to the SD card, and hard-coded a phrase to be sent out via the while() loop - this worked fine. Please see the code below:

#define REPLY_HEADER    "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n"

void Process_Client_Request()
{
    uint32_t    File_Length_Bytes;
    uint32_t    File_Length_Lines;
    uint16_t    c;
    uint32_t    LineCount = 0;

    // listen for incoming clients
    EthernetClient client = server.available();
    
      // Open serial communications and wait for port to open:
      Serial.begin(115200);
      while (!Serial);

    
    if (client)
    {
        // an http request ends with a blank line
        bool currentLineIsBlank = true;
        
        while (client.connected())
        {
            if (client.available())
            {
                char c = client.read();
                Serial.write(c);
                // if you've gotten to the end of the line (received a newline
                // character) and the line is blank, the http request has ended,
                // so you can send a reply
                if (c == '\n' && currentLineIsBlank)
                {
                    Serial.println(F("Sending response:\n"));
                    
                    // send a standard http response header
                    // use \r\n instead of many println statements to speedup data send
                    client.print(REPLY_HEADER);
                    Serial.println(F(REPLY_HEADER));

                    client.print("</body></html>");
                    Serial.println("</body></html>");

                    while (LineCount < 8000)
                    {
                        client.print("This is line number: "); client.print(++LineCount); client.print("<br>\r\n");
                        Serial.print("This is line number: "); Serial.print(LineCount); Serial.print("<br>\r\n");
                    } 
                    
                    client.print("</html></body>");
                    Serial.println("</html></body>");
                    break;
                }
                
                if (c == '\n')
                {
                    // you're starting a new line
                    currentLineIsBlank = true;
                }
                
                else if (c != '\r')
                {
                    // you've gotten a character on the current line
                    currentLineIsBlank = false;
                }
            }
        }
        // give the web browser time to receive the data
        delay(10);
        
        // close the connection:
        client.stop();
        Serial.println(F("\n\nClient disconnected"));
        
        Serial.println("\n");
    }   
}

When reading a line of text from the SD card and printing it to the client, transmission to the client terminates after about 1279 characters, give or take. When this happens, the web browser continues to wait for more data.

1
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Juraj
    Aug 13, 2021 at 9:16

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.