arduino-libraries / Ethernet

Ethernet Library for Arduino
http://arduino.cc/
261 stars 264 forks source link

Socket client first connection to Socket Server takes too long #115

Closed MyrmidonGitHub closed 5 years ago

MyrmidonGitHub commented 5 years ago

Hi!, I'm using your library as a Socket Server and I found that the first client connection attempt takes too long. I modified the AdvancedChatServer to measure the time from entering the loop to the effective client detection.

The results are very variable from execution to execution , and range from 5.7 to 36 sec.

Chat server address:192.168.1.177 5739 ms. Chat server address:192.168.1.177 12815 ms. Chat server address:192.168.1.177 36094 ms.

I checked this with both: MEGA board + keystudio W5500 shield and UNO board + W5100 shield

with similar results. As an average, I must wait 17 sec. from Arduino reset to the client connection attempt launch.

The client is latest Hercules on Win7 x64.

I attach the test code:

#include <SPI.h>
#include <Ethernet.h>
#include <utility/w5100.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network.
// gateway and subnet are optional:
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(     192, 168,   1, 177);
IPAddress myDns(  192, 168,   1,   1);
IPAddress gateway(192, 168,   1,   1);
IPAddress subnet( 255, 255, 255,   0);

// telnet defaults to port 23
EthernetServer server(23);

EthernetClient clients[8];

#define ETH_CS 10
#define SD_CS   4

byte socketStat[MAX_SOCK_NUM];
uint32_t t1;
char interval[25] = "";

void setup() {
  // Disable Ethernet
  pinMode(     ETH_CS, OUTPUT);
  digitalWrite(ETH_CS, HIGH);   

  // Disble onboard microSD
  pinMode(     SD_CS,  OUTPUT);
  digitalWrite(SD_CS,  HIGH);   

  // initialize Ethernet device
  Ethernet.init(ETH_CS);
  Ethernet.begin(mac, ip, myDns, gateway, subnet);

  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  // wait for serial port to connect. Needed for native USB port only
  while (!Serial); 

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. : infinite dummy loop...");
    // do nothing, no point running without Ethernet hardware
    while (true)
      delay(1); 
  }
  // delay to allow correct link detection...
  delay(500); 
  if (Ethernet.linkStatus() == LinkOFF)
    Serial.println("Ethernet cable is not connected.");

  // start listening for clients
  server.begin();

  // show server address
  Serial.print("Chat server address:"); Serial.println(Ethernet.localIP());

  t1 = millis();
}

void loop() {
  for (int i = 0; i < MAX_SOCK_NUM; i++) {
//    Serial.print(F("Socket#")); Serial.print(i);
    uint8_t s = W5100.readSnSR(i);
    socketStat[i] = s;
//    Serial.print(F(":0x")); Serial.print(s,16); Serial.print(F(" ")); Serial.print(W5100.readSnPORT(i)); Serial.print(F(" D:"));
    uint8_t dip[4];
    W5100.readSnDIPR(i, dip);
    for (int j=0; j<4; j++) {
      //Serial.print(dip[j],10);
      //if (j<3) Serial.print(".");
      if ((!strcmp(interval, "")) && dip[j]) { // My network is 192.168.1.x so no 000 inside...
        sprintf(interval, "%lu ms.", (millis() - t1));
        Serial.println(interval);
      }
    }
    //Serial.print(F("(")); Serial.print(W5100.readSnDPORT(i)); Serial.println(F(")"));
  }
}

As you can see, this code only checks the client presence, as it appears in the W5100, only to measure the time interval.

Is this normal?

I've been looking for this issue in Google, but no one seems to be affected...

Thank you in advance.

MyrmidonGitHub commented 5 years ago

I thought the author of the Ethernet Library reviewed the questions often.

Has anyone observed this effect?

Sometimes I can't connect the first time until half a minute has passed, which seems excessive.

The following connections are extremely fast always.

I don't know if I'm doing something wrong, but I think the example sketch should work correctly.

If not, I would like to know.

Thank you again.

Rotzbua commented 5 years ago

Has anyone observed this effect?

Yes, with Chinese clones. There are wrong resistors soldered on the board.

https://forum.arduino.cc/index.php?topic=351477.30

https://arduinodiy.wordpress.com/2017/04/12/the-w5100-bug/

MyrmidonGitHub commented 5 years ago

Thank you very much for your response.

It's unbelibebable. And maybe different manufacturers have copying each other, including the mistake.

But what I checked is a too long and random interval between the reset and the moment it was really ready to listen to customers and the resistors mistake seems to avoid any communication, right?

Rotzbua commented 5 years ago

With the wrong resistor I observed, that one of my routers did not recognize the Ethernet board. With another router I had connection issues, sometimes it freezes, sometimes package drops or a longer delay as you observed. After soldering the correct resistor to the board, the network connection worked perfectly.

MyrmidonGitHub commented 5 years ago

I have checked my W5100 shield and I have found the wrong 4x511 resistor array mistake. I added the 2 resistors (100 ohm each) and the problem persists.

With respect to the reset, it has an hex inverter, so I assume its OK.

After reflecting a little, the termination resistors should not generate the problem only on the first boot.

May someone who has a "good" ethernet shield (maybe one from arduino) check the sketch I attached?

I'd like to be sure before buying an original one ($$$)...

Thank you again.

Rotzbua commented 5 years ago

Currently I do not own the hardware. But you can check if it is a hardware or software problem.

The W5100 does replay ICMP packets by hardware functionality. This means you can run ping against the W5100. If there is a delayed ping probes then it is a hint, that the hardware has a problem. If the ping has constant time -> software problem.

PaulStoffregen commented 5 years ago

I thought the author of the Ethernet Library reviewed the questions often.

Nope. Admittedly, I wrote a relatively small amount of the code... the transition to version 2. Just so you know, maintaining these libraries is an unpaid & mostly thankless job. Developing & supporting Teensy is what pays my bills. I only worked on this library (and many others) because people trying to use it with Teensy were suffering terrible performance. For the last year or so, I've been working like mad to develop Teensy 4.0, which has left pretty much no time for maintaining open source libs.

Anyway, about your problem, may be related to issue https://github.com/arduino-libraries/Ethernet/issues/69

Also if you're going to poke directly at the socket registers (certainly not a good practice), check whether MAX_SOCK_NUM really is only 4 (or just put the number 4 in your code). See issue https://github.com/arduino-libraries/Ethernet/issues/72 and also https://github.com/arduino-libraries/Ethernet/issues/70

As for reviewing these issues often, please consider that all I've really mentioned here is some of the existing issues, which you probably could have found yourself by reading through the list of 45 that were already open. If you were me, developing a new product that actually pays the bills... would you pour much of your own (unpaid) time info reviewing issues on open source such as your's?

MyrmidonGitHub commented 5 years ago

Currently I do not own the hardware. But you can check if it is a hardware or software problem.

The W5100 does replay ICMP packets by hardware functionality. This means you can run ping against the W5100. If there is a delayed ping probes then it is a hint, that the hardware has a problem. If the ping has constant time -> software problem.

Your're right. I just have checked this way: I opened a continuous ping console from PC to Arduino and also launched my PC Client trying to connect to Arduino server.

Then I turned on and manually reset Arduino and, oh, magic! There was no ping response nor was it possible to connect the client, both for approximately 17 s. . Then the client connected to Arduino and after less than 1 s. Arduino began responding to the ping.

And so a lot of times, some with more than 17s. and others with less.

As you stated, it seems a hardware problem, so I'll try to contact them and see what happens.

Rotzbua, you have hit the nail. Thank you very much.

MyrmidonGitHub commented 5 years ago

I thought the author of the Ethernet Library reviewed the questions often.

Nope. Admittedly, I wrote a relatively small amount of the code... the transition to version 2. Just so you know, maintaining these libraries is an unpaid & mostly thankless job. Developing & supporting Teensy is what pays my bills. I only worked on this library (and many others) because people trying to use it with Teensy were suffering terrible performance. For the last year or so, I've been working like mad to develop Teensy 4.0, which has left pretty much no time for maintaining open source libs.

Anyway, about your problem, may be related to issue #69

Also if you're going to poke directly at the socket registers (certainly not a good practice), check whether MAX_SOCK_NUM really is only 4 (or just put the number 4 in your code). See issue #72 and also #70

As for reviewing these issues often, please consider that all I've really mentioned here is some of the existing issues, which you probably could have found yourself by reading through the list of 45 that were already open. If you were me, developing a new product that actually pays the bills... would you pour much of your own (unpaid) time info reviewing issues on open source such as your's?

Hi, PaulStoffregen. I thank you your efforts.

About MAX_SOCK_NUM, as I said before, the problem happens only after the reset, so I don't believe it can be.

As I answered to Rotzbua (previous post), after checking the hardware ping, it seems to be a hardware problem.

About your time ... I agree, I would do the same as you, but think that I came here through the ethernet 2.0 library and nothing indicated whether the library was paid or not. Anyway, I thank you for your effort.

As for using the socket registers directly, think I initially tried the Arduino IDE example (AdvancedChatServer) and when I found the problem of the 17s. I tried to modify the sketch to identify the origin of the problem. With the sketch I uploaded to GitHub I tried to be sure that I was detecting the client IP and was only useful after reset.

As I said to Rotzbua, I'll try to contact Wiznet and see what happens.

By the way, did you ever notice such a delay responding a ping after reset?

MyrmidonGitHub commented 5 years ago

Well, here again.

As I said, I contacted Wiznet, through their forum: https://forum.wiznet.io/t/topic/6610/4

and as you can see, it was my fault, the delay was introduced by my router, so I attached the arduino to a simple switch and voilà, less than 2s., probably due to my sketch setup.

Thank you very much to all of you for your assistance.

MyrmidonGitHub commented 5 years ago

If nobody has a doubt, I will close the thread.