icmp ping prevents ntp from terminating

The program below demonstrate this phenomenon:
it take long for UDP.beginPacket to terminate
and UDP.endPacket appears to never terminate
If preceded by a ping.

I am using ping to check the Internet connectivity and recycle the router’s power in case of failure but then the program get blocked when it synchronizes to a time server.

Both functions: time and connectivity test are vital in this project; any idea how to progress? There are means to get the approximate time from an HTTP server but, now I am afraid that the ping code hides other flaws and I rather have a precise time

Many thanks in advance

#include <ICMPPing.h>
#include <Ethernet.h>
#include <SPI.h>
#include <EthernetUdp.h>
#define TIMEZONE_SECS 0

SOCKET pingSocket = 0;
ICMPPing ping(pingSocket, (uint16_t)random(0, 255));
IPAddress googleSecondaryDNS(8,8,4,4);
char timeServer[] = "time.nist.gov";

int ntpPort=123;
unsigned int localPort = 8888;       // local port to listen for UDP packets maybe anything??
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets


// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
long epoch;

//**********change per your net***************
byte mac[] = { 0x00, 0xaa, 0xbb, 0xcc, 0xde, 0x02};
IPAddress myIP   (192,168,002,123);    
IPAddress netDNS (192,168,002,001);
IPAddress gateway(192,168,002,001);
IPAddress subnet (255,255,255,000);


void setup() {
  Serial.begin(9600);
  Serial.println("Starting");
  Ethernet.begin(mac, myIP, netDNS, gateway, subnet);
  Udp.begin(localPort);
  Serial.println("setup terminated");
}

void loop() {
  Serial.print("P or p to ping before ntp - any for ntp without ping");
  while (Serial.available()<=0);
  char answer=Serial.read();
  Serial.print(" you entered "); Serial.println(answer);
  boolean doPing=(answer=='p')||(answer=='P');
  if(doPing) if(pinger()) Serial.println("pinged successfully"); else Serial.println("pinged failed");
  if(getEpoch(timeServer, &epoch)) {Serial.print("Success, epoch is "); Serial.println(epoch);}
  else Serial.print("failed to get epoch"); 
}

boolean pinger(){
  boolean status;
  ICMPEchoReply echoReply=ping(googleSecondaryDNS, 4);
  if (echoReply.status == SUCCESS)status=true;
  else status=false;
  delay(5000);
  return status;
}

boolean getEpoch(char* ntpServer, long* epoch){
  Serial.println("sending ntp packet");
  sendNTPpacket(ntpServer); 
  delay(1000);
  Serial.println("ntp packet sent");
  if ( Udp.parsePacket() ) {
    // We've received a packet, read the data from it
    Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
    //the timestamp starts at byte 40 of the received packet and is four bytes,
    // or two words, long. First, esxtract the two words:
    
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
    // combine the four bytes (two words) into a long integer
    // this is NTP time (seconds since Jan 1 1900):
    unsigned long secsSince1900 = highWord << 16 | lowWord;
      // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
    const unsigned long seventyYears = 2208988800UL;
    // subtract seventy years:
    *epoch = secsSince1900 - seventyYears +(unsigned long) +TIMEZONE_SECS;
    delay(10000);
    return true;
  }
  else return false;
}

// send an NTP request to the given time server
void sendNTPpacket(char* ntpServer){
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49;
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
  // all NTP fields have been given values, now
  // you can send a packet requesting a timestamp:
  Serial.print(F("Udp.beginPacket is "));Serial.println(Udp.beginPacket(ntpServer, ntpPort));
  Serial.print(F("Udp.write is "));Serial.println(Udp.write(packetBuffer, NTP_PACKET_SIZE));
  Serial.print(F("Udp.endPacket is "));Serial.println(Udp.endPacket());
}

Add this function to your sketch and call this when you want to check the socket status. It should be W5100/W5200/W5500 compatible.

#include <utility/W5100.h>

byte socketStat[MAX_SOCK_NUM];

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

Socket status codes:
0x0 = available
0x14 = listening
0x17 = connected
0x1C = waiting for close
0x22 = UDP

I don’t know what the ICMP status code is.

I changed the ping socket # from 0 to 1 per Blake Foster's suggestion that it might collide with ntp and it stopped blocking ntp. My concern is that other protocols be corrupted if they happen to use socket#1 (!)