W5500: creating new TCP session

Hi,
I am using W5500 with arduino Mega to interface to a device.

The device acts as a TCP client and connects to the TCP server which is the Mega board.

The device sends a keepalive timer in one of the messages based on which the Server needs to periodically send some data.

The code that I have written works fine till the session is maintained. But when the device breaks the connection sometimes and tries to re-establish,
then no data is sent from the server to the device.

I am checking the client in the following way:

  tempC = g_server.available();
  if (tempC) {
    client  = tempC;
  }

I am doing this so that, when there is no data from the client to the server, the server keeps on sending periodic data to the client which was connected previously

But, if the client disconnects and connects with different port id, then the server should send data to new client.
But, this particular thing is not happening.
Can anyone suggest some reason?

void OPENAMIP()
{

  static uint32_t lastTime = 0;
  // byte CS=0;
  char *ret = NULL;

  static boolean recvInProgress = false;
  static byte ndx = 255;
  char endMarker = END_MARKER_OPENAMIP;
  char rc = 0;


  tempC = g_server.available();
  if (tempC) {
    client  = tempC;
  }
  if (client) {


    while (client.available() > 0 && g_TCPPktTransferComplete == false) {
      rc = client.read();
      //  Serial.write(rc);
      if (recvInProgress == true) {
        if ((rc == endMarker) or (ndx >= MAXPACKETSIZE_OPENAMIP - 1)) //either end of packet reached or buffer overflow
        {
          g_receivedCharsfromMODEM[ndx] = '\0'; // terminate the string
          recvInProgress = false;
          ndx = 255;
          g_TCPPktTransferComplete = true;

        }
        else  {
          g_receivedCharsfromMODEM[ndx] = rc;
          if (rc == 'F') {
            client.write(g_STATUS_OPENAMIP);  // need to get the status from control card before this based to ack lock status
            client.write(CR);
            client.write(NL);
          }
          ndx++;
        }
      }
      else if (ndx == 255) {
        recvInProgress = true;
        g_modemDataReady = false;
        ndx = 0;
        g_receivedCharsfromMODEM[ndx] = rc;
        ndx++;


      }
    }




    if ((alive_flag_updated) && (millis() - lastTime > ((g_openamip_alive_interval - 1) * 1000))) { //keep alive
      lastTime = millis();
      client.write(g_header);
      client.write(g_latSign);
      client.write(g_LAT);
      client.write(space);
      client.write(g_longSign);
      client.write(g_LONG);
      client.write(footer);
      client.write(CR);
      client.write(NL);
    }


    if (g_TCPPktTransferComplete == true) {

      ret = strstr(g_receivedCharsfromMODEM, ALIVE_INTERVAL_MSG);
      if (ret != NULL) {
        ret = strtok(ret, " ");
        ret = strtok(NULL, "\r");
        g_openamip_alive_interval = atoi(ret);
        alive_flag_updated = true;
        client.write("a 2");
        client.write(CR);
        client.write(NL);
        Serial.print("CLIENT: ");
        Serial.println(client.remoteIP());
      }

      ret = strstr(g_receivedCharsfromMODEM, WHERE_MSG);
      if (ret != NULL) {
        ret = strtok(ret, " ");
        ret = strtok(NULL, "\r");
        g_openamip_where_interval = ret[0] - '0';

        client.write(g_header);
        client.write(g_latSign);
        client.write(g_LAT);
        client.write(space);
        client.write(g_longSign);
        client.write(g_LONG);
        client.write(footer);
        client.write(CR);
        client.write(NL);
      }

      
      g_modemDataReady = true;
      g_TCPPktTransferComplete = false;
    }
  }
}

This is the main function which calls the OPENAMIP() function continously


int main (void)
{
  //initialisation related tasks
  init_all_peripherals ();	
/************* Setup the interrupts for Buttons *******************/
  pinMode (ACQUIRE_PIN, INPUT_PULLUP);
  attachInterrupt (digitalPinToInterrupt(ACQUIRE_PIN), acquire, FALLING);	//ACQUIRE_PIN is 4 for INT.4
  pinMode (STOW_PIN, INPUT_PULLUP);
  attachInterrupt (digitalPinToInterrupt(STOW_PIN), stow, FALLING);	//A
/******************************************************************/


  while (1)
    {
      //receive data from 3 sensors WITHOUT BLOCKING and no delay
      //send data to CC if data acquisition complete

      acquire_action();
      stow_action();
      receiveDataFromGPS();
      processAndSendGPSData();	
      receiveDataFromInclinometer();
      processAndSendInclinometerData ();	
      receiveDataFromCompass();
      processAndSendCompassData();	
      receiveDataFromCC();
      processDatafromCC();
      OPENAMIP();
      receiveBUCData();
      processBUCData();
      sendNewBUCparamteresToCC();
      
    }
  return 0;
}

server.available only returns a client with data available. does it explain the problem?

I check server.available() in a temporary variable for this reason only.
Because I want to send data to the client when there is no data coming from the client but the session is still being maintained.

In the first run, data will come from the client which will have a keep alive timer value, then the client will keep silent and wait for periodic data.
In second run, I will check the server.available in temporary variable tempC, if it doesn't return anything then I keep sending data to old client.
It tempC returns something, I assume that the client has either sent some data, or the client has reconnected, so I update the client object.

And I am able to send this periodic data to client successfully.
Problem only comes when the client closes the connection and starts a new connection. In that case I am not able to send data to new client even after it connects to the server

I forgot to show my main function which calls this function in while loop


int main (void)
{
  //initialisation related tasks
  init_all_peripherals ();	
/************* Setup the interrupts for Buttons *******************/
  pinMode (ACQUIRE_PIN, INPUT_PULLUP);
  attachInterrupt (digitalPinToInterrupt(ACQUIRE_PIN), acquire, FALLING);	//ACQUIRE_PIN is 4 for INT.4
  pinMode (STOW_PIN, INPUT_PULLUP);
  attachInterrupt (digitalPinToInterrupt(STOW_PIN), stow, FALLING);	//A
/******************************************************************/


  while (1)
    {
      //receive data from 3 sensors WITHOUT BLOCKING and no delay
      //send data to CC if data acquisition complete

      acquire_action();
      stow_action();
      receiveDataFromGPS();
      processAndSendGPSData();	
      receiveDataFromInclinometer();
      processAndSendInclinometerData ();	
      receiveDataFromCompass();
      processAndSendCompassData();	
      receiveDataFromCC();
      processDatafromCC();
      OPENAMIP();
      receiveBUCData();
      processBUCData();
      sendNewBUCparamteresToCC();
      
    }
  return 0;
}

but does the client send some data after reconnect? (after reconnect it is a new client.)
you can have more control over clients with the accept() function
https://www.arduino.cc/en/Reference/EthernetServerAccept

Yes,

whenever the client reconnects, it always sends a long data packet.

Also, right now I am simulating it with a TCP client software on my PC and closing and reconnecting the session and sending data after that. Still I am not receiving any data in my client after reconnection

Thanks, I will check this.

This seems like a much better way to do it. I will try this method.
Thanks a lot

and the g_TCPPktTransferComplete == false part of the condition. shouldn't that reset on new connection?

and the g_TCPPktTransferComplete == false part of the condition. shouldn't that reset on new connection?

I don't think that is required, it is set to true when I receive a full packet of data according to the protocol that I am using. It is a bad name, I should have kept the name g_ModemTransferComplete as it doesn't signify TCP transfer, but the framing of data which comes over the TCP

It seems the problem was solved when I replaced server.available() with server.accept().
I will read the documentation thoroughly.
Thanks a lot for the help!

Do you have to reconnect to reset the data packets or not?
I ask myself the same question if my device does not pick up well!