Hey. First of all, thank you for the great work on this library.
In last few days I have been trying to port a webserver library I made ages ago to work with this new library. I got it working now, but it seemed a bit slow when sending data, even for smaller pages. So I have made some tests just using the base examples to try and reproduce the problem.
I created a function to create a buffer of a specific size with a constant value, then send it
Code:
void sendBuffer(uint8_t client, uint8_t value, uint16_t size)
{
byte send_buffer[size];
memset(send_buffer, value, size);
clients[client].write(send_buffer, size);
//clients[client].flush();
checkTimer(); // Prints the time elapsed since startTimer() was called
}
Then called that function on a loop, so I could send any amounts of data with different buffer sizes.
Code:
startTimer();
for (size_t j = 0; j < 100; j++)
{
Serial.print(j); Serial.print("\t");
sendBuffer(i, 'A'+(j%26), 256);
}
I also tried using different values for Ethernet.setSocketSize() in the setup.
The values below are the result of the checkTimer() function call, printed after each client.write();
In this specific case I was using an 8K buffer in setSocketSize() and was doing 256 bytes writes each time.
Looking only at this, seemed like something happend when the buffer fills up. Each write took less then 10uS for the first 8KB, then there was a massive delay. I tried with different sockets and write size combinations and this is consistent. This would happen only after I write more than the buffer size.
0 Timer:0(S) 0(mS) 8(uS)
1 Timer:0(S) 0(mS) 12(uS)
2 Timer:0(S) 0(mS) 16(uS)
3 Timer:0(S) 0(mS) 20(uS)
4 Timer:0(S) 0(mS) 25(uS)
5 Timer:0(S) 0(mS) 29(uS)
6 Timer:0(S) 0(mS) 34(uS)
7 Timer:0(S) 0(mS) 38(uS)
8 Timer:0(S) 0(mS) 42(uS)
9 Timer:0(S) 0(mS) 47(uS)
10 Timer:0(S) 0(mS) 51(uS)
11 Timer:0(S) 0(mS) 56(uS)
12 Timer:0(S) 0(mS) 60(uS)
13 Timer:0(S) 0(mS) 65(uS)
14 Timer:0(S) 0(mS) 69(uS)
15 Timer:0(S) 0(mS) 74(uS)
16 Timer:0(S) 0(mS) 78(uS)
17 Timer:0(S) 0(mS) 82(uS)
18 Timer:0(S) 0(mS) 87(uS)
19 Timer:0(S) 0(mS) 92(uS)
20 Timer:0(S) 0(mS) 96(uS)
21 Timer:0(S) 0(mS) 101(uS)
22 Timer:0(S) 0(mS) 105(uS)
23 Timer:0(S) 0(mS) 110(uS)
24 Timer:0(S) 0(mS) 114(uS)
25 Timer:0(S) 0(mS) 119(uS)
26 Timer:0(S) 0(mS) 123(uS)
27 Timer:0(S) 0(mS) 128(uS)
28 Timer:0(S) 0(mS) 132(uS)
29 Timer:0(S) 0(mS) 137(uS)
30 Timer:0(S) 0(mS) 142(uS)
31 Timer:0(S) 0(mS) 146(uS)
32 Timer:0(S) 40(mS) 40334(uS)
33 Timer:0(S) 81(mS) 81285(uS)
34 Timer:0(S) 81(mS) 81290(uS)
35 Timer:0(S) 81(mS) 81295(uS)
36 Timer:0(S) 81(mS) 81299(uS)
37 Timer:0(S) 81(mS) 81304(uS)
38 Timer:0(S) 81(mS) 81902(uS)
39 Timer:0(S) 81(mS) 81907(uS)
40 Timer:0(S) 81(mS) 81911(uS)
41 Timer:0(S) 81(mS) 81916(uS)
42 Timer:0(S) 81(mS) 81921(uS)
43 Timer:0(S) 81(mS) 81925(uS)
Initially I assumed it would be a buffering thing. Maybe I was calling the writes faster than the data was being sent, and something would be stuck. But then, I also tried sending bigger amounts of data (several MB). I was expecting it to maybe hang up a few times along the way while it was catching up. But in every single test I made, it always has that one single hick-up the first time the buffer fills up, then it's fast all the way to the end. I also tried using the flush() method, but that made things way slower.
So I went a little deeper and used Wireshark to look at the packages being sent. And here the problem seems to be in the very first packages. We can see it sent the first frame with 256 bytes, which was my first buffer. Then the second package (the one in gray) had a payload of 1460, containing data from multiple writes(). This package was sent 40ms after the first one. Then the next package was similar, and it took another 41ms. But after these two, all the other packages took way less than a milisecond.
I tried many different combinations, and the behaviour is always the same. The first write() goes in the first package. Then the next few writes() are packed together in the second package, and its transmitted around 40ms after the first. Then the third is typically the same. And after this, all seems to stabilize and there are no more delays. Even if i only do 2 small writes(), in the Teensy prints it says they took like 10uS, but in Wireshark I see the the second package being sent 40ms after the first one. Could the library maybe be waiting for more data to fill a frame or something like that? And when it actually has enough data it does not realize it and only sends the frame after a timeout? Now I'm just guessing...
Let me know your thoughts, and if you'd like to make any other tests let me know.