telnet server and the ethernet card limitations

Hey folks.

I am building a system that has two Arduinos each with an ethernet card. One is a telnet server and the other is a telnet client. A string is sent from the client to the server and the output pins on the server are toggled based on the string sent. I am trying to make it as resilient as possible so that it can be a set and forget system. The idea being that if the network connection goes down the system will automaticily re-establishes the connection. This works but not perfectly. In testing it, I have found that if I unplug the network cable and wait a short time and then re connect it, the system re-established the connection. The problem is, it work four times and then it never works again until I reboot the device with a hard reset or a power cycle.

I am going to be sending the data over a long link that uses a microwave ethernet connection that could go down every once in a while so I think this is important.

I believe the issue is that the w5100 only have capacity for 4 socket connections an is not dropping the "old" connection even thought i do a client.stop when my sketch notices the disconnect.

I can not seam to find anything dealing with this using any of the search key word I can think of.

Anyone had to deal with this before?

Cheers

If you want a true telnet server, you should learn to use the basic w5100 functions. They are in the ethernet library utility directory.
w5100.h
w5100.cpp
socket.h
socket.cpp

Here is my code from my web server in the playground. This disconnects any client that has been connected for more than 30 seconds. You need to modify this to suit your needs.

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

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


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);
  }
}

edit: You may need this part also. It displays the socket status.

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(")"));
  }
}

Perhaps I didnt include that my system work. What I am asking is if there is a way to kill a socket that gets disconnected by an ethernet problem. a method that does more than the client.stop and frees the orphaned sockets.

If the client sends a disconnect message, you don't need to force it to close. If the client doesn't send a disconnect message, that orphans the socket. The checkSockStatus function above will close a socket that has been orphaned by its client. It is designed for a web server (not telnet server), so it closes the socket after thirty seconds. You must change that to a time that is appropriate to a telnet server. You should reset the time if any characters are received from a telnet client also.

Now I see what you meant.

I will give that a go.

Thank you very much for pointing that out!

Ok Surfertim I have a question. I get that with a web server you can deal with a disconnect and it would be ok. i have been giving this some thought but I have a problem with this approach. unless i know what socket is the current "active" socket, I can not increment the timer for that socket so as to make sure that one does not get disconnected. how would i go about doing that?

Also I have another question. in the "checkSockStatus() above, how does it acutely disconnect the orphaned sockets. i looked and close() is for files in the SD card library. without a link of some sort to the socket how does it know that you are telling it to close orphaned sockets?

Cheers.

You will probably need to use the socket and w5100 parts of the ethernet library. There is not much in the standard ethernet library that will help you with the telnet server code. Look in the utility directory of the ethernet library directory.

And close is a function in the socket library. This is in socket.cpp.

/**
 * @brief	This function close the socket and parameter is "s" which represent the socket number
 */
void close(SOCKET s)
{
  W5100.execCmdSn(s, Sock_CLOSE);
  W5100.writeSnIR(s, 0xFF);
}

SurferTim.

Thank you for your help.

I realized that I was complicating things. What I was looking for was a complete reset of the sockets and I was able to accomplish with the following.

void closeSockets()
{
  
  for (int i = 0; i < MAX_SOCK_NUM; i++) {
          close(i);
  }
  
}

I call this from my reset function and it works great now.

Thanks again for the direction.

Have a great holiday season.

Cheers.