Hi,
I've got a Teensy LC connected to a wiznet W550 using the Ethernet library.
I've edited the library slightly so when I call client.read everything happens as it should, except I've commented out the actual data read.
This is because I'm trying to get the max speed the network can provide.
I'm getting some interesting results and I was wondering if anyone could help please?
When I host a http server on my laptop, and download a 10MB test file from the local network, I get the following results:
4 sockets (small buffer) 4181kbps
1 socket (biggest buffer) 11766kbps
Which obviously shows the buffer size is affecting the max speeds. From this I would assume that I could download a file from the internet, and my internet connection speed of max 1000kbps (i know it's cheap) would be the bottleneck, not the W550.
However, when I download a file from a number of servers hosting the same 10MB test file I get the following results NOTE my laptop maxes out as expected at 1000kbps from these servers:
4 sockets 91kbps
1 max socket 500kbps
This shows the W550 is the bottleneck, and the connection speed is limited by the buffer size and Teensy speed.
Isn't this weird? If the W550 can download 10mbps on the local network, why is it bottlenecking at 500kbps when downloading from the internet? How are these situations changing its max download?
I'd appreciate it if anyone could shed some light on the situation.
ethernetclient.cpp implements new function
and socket.cpp implements recvnoread
To mess with the buffer sizes, you need to edit Ethernet.h
and uncomment
and change the max socket num define to 1 or 4 as necessary
I've got a Teensy LC connected to a wiznet W550 using the Ethernet library.
I've edited the library slightly so when I call client.read everything happens as it should, except I've commented out the actual data read.
This is because I'm trying to get the max speed the network can provide.
I'm getting some interesting results and I was wondering if anyone could help please?
When I host a http server on my laptop, and download a 10MB test file from the local network, I get the following results:
4 sockets (small buffer) 4181kbps
1 socket (biggest buffer) 11766kbps
Which obviously shows the buffer size is affecting the max speeds. From this I would assume that I could download a file from the internet, and my internet connection speed of max 1000kbps (i know it's cheap) would be the bottleneck, not the W550.
However, when I download a file from a number of servers hosting the same 10MB test file I get the following results NOTE my laptop maxes out as expected at 1000kbps from these servers:
4 sockets 91kbps
1 max socket 500kbps
This shows the W550 is the bottleneck, and the connection speed is limited by the buffer size and Teensy speed.
Isn't this weird? If the W550 can download 10mbps on the local network, why is it bottlenecking at 500kbps when downloading from the internet? How are these situations changing its max download?
I'd appreciate it if anyone could shed some light on the situation.
Code:
/*
Web client
This sketch connects to a website (http://www.google.com)
using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
created 18 Dec 2009
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe, based on work by Adrian McEwen
*/
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//https://www.futurehosting.com/network-test-files/
//IPAddress server(87,76,31,34); // numeric IP for futurehosting
//IPAddress server(192,168,1,248);
//char server[] = "speedtest.tele2.net"; // name address for Google (using DNS)
//char server[] = "london.futurehosting.com";
//char server[] = "www.google.com";
char server[] = "www.ovh.net";
// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(192, 168, 0, 177);
IPAddress myDns(192, 168, 0, 1);
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;
// Variables to measure the speed
unsigned long beginMicros, endMicros;
unsigned long byteCount = 0;
bool printWebData = true; // set to false for better speed measurement
void setup() {
// You can use Ethernet.init(pin) to configure the CS pin
//Ethernet.init(10); // Most Arduino shields
//Ethernet.init(5); // MKR ETH shield
//Ethernet.init(0); // Teensy 2.0
//Ethernet.init(20); // Teensy++ 2.0
//Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet
//Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// start the Ethernet connection:
Serial.println("Initialize Ethernet with DHCP:");
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// Check for Ethernet hardware present
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println("Ethernet shield was not found. Sorry, can't run without hardware. :(");
while (true) {
delay(1); // do nothing, no point running without Ethernet hardware
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println("Ethernet cable is not connected.");
}
// try to congifure using IP address instead of DHCP:
Ethernet.begin(mac, ip, myDns);
} else {
Serial.print(" DHCP assigned IP ");
Serial.println(Ethernet.localIP());
}
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.print("connecting to ");
Serial.print(server);
Serial.println("...");
// if you get a connection, report back via serial:
if (client.connect(server, 80)) {
Serial.print("connected to ");
Serial.println(client.remoteIP());
// Make a HTTP request:
client.println("GET /files/100Mb.dat");
//client.println("Host: speedtest.tele2.net");
//client.println("Host: 192.168.1.248");
client.println("Host: www.ovh.com");
client.println("Connection: close");
client.println();
} else {
// if you didn't get a connection to the server:
Serial.println("connection failed");
}
beginMicros = micros();
}
void loop() {
// if there are incoming bytes available
// from the server, read them and print them:
if(client.available()) {
uint16_t byteLen = client.readNoRead();
//Serial.println(byteLen);
byteCount = byteCount + byteLen;
//Serial.write(client.read());
//cpuLoadSleep();
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
endMicros = micros();
Serial.println();
Serial.println("disconnecting.");
client.stop();
Serial.print("Received ");
Serial.print(byteCount);
Serial.print(" bytes in ");
float seconds = (float)(endMicros - beginMicros) / 1000000.0;
Serial.print(seconds, 4);
float rate = (float)byteCount / seconds / 1000.0;
Serial.print(", rate = ");
Serial.print(rate);
Serial.print(" kbytes/second");
Serial.println();
// do nothing forevermore:
while (true) {
delay(1);
}
}
}
ethernetclient.cpp implements new function
Code:
int EthernetClient::readNoRead()
{
return Ethernet.socketRecvNoRead(sockindex);
}
and socket.cpp implements recvnoread
Code:
int EthernetClass::socketRecvNoRead(uint8_t s)
{
uint16_t len = 65535;
// Check how much data is available
int ret = state[s].RX_RSR;
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
if (ret < len) {
uint16_t rsr = getSnRX_RSR(s);
ret = rsr - state[s].RX_inc;
state[s].RX_RSR = ret;
//Serial.printf("Sock_RECV, RX_RSR=%d, RX_inc=%d\n", ret, state[s].RX_inc);
}
if (ret == 0) {
// No data available.
uint8_t status = W5100.readSnSR(s);
if ( status == SnSR::LISTEN || status == SnSR::CLOSED ||
status == SnSR::CLOSE_WAIT ) {
// The remote end has closed its side of the connection,
// so this is the eof state
ret = 0;
} else {
// The connection is still up, but there's no data waiting to be read
ret = -1;
}
} else {
if (ret > len) ret = len; // more data available than buffer length
uint16_t ptr = state[s].RX_RD;
//if (buf) read_data(s, ptr, buf, ret);
ptr += ret;
state[s].RX_RD = ptr;
state[s].RX_RSR -= ret;
uint16_t inc = state[s].RX_inc + ret;
if (inc >= 250 || state[s].RX_RSR == 0) {
state[s].RX_inc = 0;
W5100.writeSnRX_RD(s, ptr);
W5100.execCmdSn(s, Sock_RECV);
//Serial.printf("Sock_RECV cmd, RX_RD=%d, RX_RSR=%d\n",
// state[s].RX_RD, state[s].RX_RSR);
} else {
state[s].RX_inc = inc;
}
}
SPI.endTransaction();
//Serial.printf("socketRecv, ret=%d\n", ret);
return ret;
}
To mess with the buffer sizes, you need to edit Ethernet.h
and uncomment
Code:
#define ETHERNET_LARGE_BUFFER
and change the max socket num define to 1 or 4 as necessary