Bug in println(F( or Ethernet library ?!?

Here's a sample piece of code :

 EthernetClient client;

 client.println(F("HTTP/1.0 404 Not Found"));
 client.println(F("Content-Type: text/html"));
 client.println();
 client.println(F("<h2>Error 404</h2>"));
 client.println(F("<s2>The file does not exist.<s2>"));

This code works, but it produces TCP packets with a length of 1 byte (!), so one packet for each character to be transmitted, which multiplies traffic by more than 10 !

One should expect that at least one line goes into one packet.

Is there any solution or workaround for this issue ?

what proof did you bring? (it's not the case to my knowledge with the current Ethernet library and common Ethernet chips. the writes are buffered)

i can see that in Wireshark

"println( " does produce one line per packet, but "println(F(" makes one character per paket. Try it yourself, if you don't believe me !

Which Arduino board?

Please post your entire sketch. I suspect you have some delays that are forcing it to do that.

Could be caused by print reading from program memory one character at a time

size_t Print::print(const __FlashStringHelper *ifsh)
{
  PGM_P p = reinterpret_cast<PGM_P>(ifsh);
  size_t n = 0;
  while (1) {
    unsigned char c = pgm_read_byte(p++);
    if (c == 0) break;
    if (write(c)) n++;
    else break;
  }
  return n;
}

Printing a null-terminated char array calls write() with the array instead of individual characters

size_t Print::print(const char str[])
{
  return write(str);
}

You might need to copy the text from progmem to a buffer to get it sent as a single packet.

1 Like

It does call write() which indeed adds one byte to the underlying driver but my understanding was that the layer below was doing the buffering and sending

What chip do you have?

TL;DR use my StreamLib for buffering

yes - don't use the F-Makro with the ethernet client.

Use a buffer or the StreamLib library

On this page I cover that topic:

1 Like

Thanks to all of you.
The issue is quite clear now and the best solution is probably the StreamLib library.
I'll give it a try.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.