I'm using an Arduino Uno with an Ethernet Shield and the arduino.cc Ethernet library for a custom TCP-based message-exchanging chat-like protocol. Specifically I'm using the Client class with its print()
and println()
methods. It works.
But on each single print()
or println()
call a whole TCP packet is sent. Also if just one byte is printed, a whole TCP packet is sent over the IP layer. I mean there's a lot of TCP packets with very few data inside. In other words there's a big overhead.
For example take this message that my Arduino successfully sends and my server successfully receives:
i-am EEEEEEEE-EEEEEEEE-EEEEEEEE-EEEEEEEE\r\n
The code is the following:
stream.print("i-am");
stream.print(' ');
for (byte i = 0 ; i < SERIAL_CODE_LENGTH ; i++){
if ( i % 4 == 0 && i != 0 ){
stream.print('-');
}
if (serialCode[i] < 16){
stream.print('0');
}
stream.print(serialCode[i], HEX);
}
stream.println();
All that EE
are hexadecimal byte values from an array and they are fine. But I can see from Wireshark that those 42 bytes (that could be fit in a single packet) are sent in 22 TCP packets (one for each print
call in my code)!
How can I avoid this fragmentation? Is there a way to use an hardware or software buffer to group data before to send (Nagle's algorithm)?
With other SDKs the data are buffered by default and they're sent when the buffer is full or when an explicit "push" or "flush" call occurs. I checked Client flush
method and it looks to be a different beast...