arduino-libraries / Ethernet

Ethernet Library for Arduino
http://arduino.cc/
257 stars 262 forks source link

Socket close function not working in 2.0.0 #82

Open fredlcore opened 5 years ago

fredlcore commented 5 years ago

In order to prevent frozen sockets to lockup network connections, this code here used to work until version 1.1.2 (taken from http://forum.arduino.cc/index.php?topic=291958.msg2040300#msg2040300):

#include <utility/w5100.h>
#include <utility/socket.h>

byte socketStat[MAX_SOCK_NUM];
unsigned long connectTime[MAX_SOCK_NUM];

void loop() {

  if(Serial.available()) {
    if(Serial.read() == 'r') ShowSockStatus();   
  }

  checkSockStatus();

  // rest of your loop code
}

// add these functions

void ShowSockStatus()
{
  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(".");
    }
    Serial.print(F("("));
    Serial.print(W5100.readSnDPORT(i));
    Serial.println(F(")"));
  }
}

void checkSockStatus()
{
  unsigned long thisTime = millis();

  for (int i = 0; i < MAX_SOCK_NUM; i++) {
    uint8_t s = W5100.readSnSR(i);

    if((s == 0x17) || (s == 0x1C)) {
        if(thisTime - connectTime[i] > 30000UL) {
          Serial.print(F("\r\nSocket frozen: "));
          Serial.println(i);
          close(i);
        }
    }
    else connectTime[i] = thisTime;

    socketStat[i] = W5100.readSnSR(i);
  }
}

After adjusting the includes for 2.0.0, the "close(i)" still won't compile because the function is no longer provided for. When I take the 1.1.2 code of "close", the Arduino freezes whereas the same script with library 1.1.2 works perfectly fine.

Is there any way to fix this or at least work around it (without downgrading from version 2.0.0)?

Xtreemtec commented 5 years ago

Well i managed to make a "dirty" work around for now. But not really a clean solution! Because it normally poll's for XML data every 2 seconds in my program. I build in a counter, if the counter reaches a certain amount it will call a new function i wrote to make the socketClose public:

void EthernetServer::killsock(uint8_t i) { //Ethernet.socketDisconnect(i); Ethernet.socketClose(i); SerialUSB.println("<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>"); }

By this i'm able to kill the connections. So when the XML isn't polled anymore the counter will go up and activate a killsock command for all 4 ports.

This works for me now, but it is rather nasty and should not be necessary to do so. ;) Would like to know how you fixed it on your end.

SapientHetero commented 5 years ago

I fixed numerous issues in my updated version of the library, which is posted at https://github.com/SapientHetero/Ethernet. README.rtf lists all the changes I made.

Make sure to read the part at the end about manageSockets(), which is where sockets are managed. You'll need to call it in every pass through your webserver in order for it to work. Post any questions as an issue on that page and I'll respond as quickly as possible.