w5500 can not connect to server after running a couple of hours

  1. I used the official reference codes.
  2. It works well and even runs correctly for days without any issue in my company.
  3. It can work and connect to server correctly in my customer’s company and also runs for a couple of hours correctly.
  4. but it can not connect to server after correctly running a couple of hours, when I check the log, I found the socket established well, and after issuing a connect command, the snsr was always syncsent status, when I powered off and on again, the problem reproduced.
  5. when the problem occured, if I used the same cable to plug into my computer, the computer can work correctly.

Please anyone help.

Peter Fu

[quote=“peter1104, post:1, topic:3190”]
4) but it can not connect to server after correctly running a couple of hours, when I check the log, I found the socket established [opened?] well, and after issuing a connect command, the snsr was always syncsent status,[/quote]
This needs further troubleshooting:

  1. Use Wireshark or any other network monitoring tool to see contents of SYN packet W5500 sends, and if server replies. As an example, if you have rights for the server, install wireshark there (as the server is the one of the nodes in the communication);
  2. when issue happens, perform dump of all common and socket registers to ensure they are set properly.

You mean W5500 is stuck in SYNSENT state, you power cycle W5500, and after it initializes it still can not connect to the server? If yes, then what do you do to make it cinnecting again?

So you unplug cable from the W5500 and plug into PC, that PC using this cable and this port of the switch cable is connected to can connect to the server?

1 Like

thanks for your reply.
#1 I am not familiar with wireshark, but I will try.
#2 I will try to dump all.
#3 even power w5500 off and on for a couple of times, w5500 can not connect to the server. but if I tried, for example, 20 times, there might be one successful connection, or if I ping the w5500 ip(when it is in synsent status), w5500 can connect server immediately.
#4 yes, PC can use the same cable and port to connect server, so it is not problem with cable and port of switch.

By the way, before connecting to server, w5500 can get ip assigned from dhcp server (I copied the official reference codes about how to parse dhcp) successfully. In my codes, w5000 get ip assigned from dhcp server and connect to application server immediately, shall I need to wait for some time before connecting and after getting ip assigned?

Peter Fu

Sounds like there’s an issue with ARP cache, and not only at W5500 side.

Let’s make a quick check:

  1. in common register area you populate GAR, SUBR, SHAR and SIPR? And your SHAR does not have two lowest bits in first octet set (which make MAC address locally administered and multicast)?
  2. you close and reopen socket before you make next (new) connection?
  3. you DO use different Sn_PORT source socket port numbers every time you connect (you do NOT reuse port #)?

@@1. codes below is to get register set from response of dhcp, also, I copied the mac of my wifi module (wihch driving w5500 through spi, the mac is officially assigned, and wifi module won’t connect any wifi route or switch), so it won’t be a locally admined or multicast, by the way, when first plugging in the cable, it works for a couple of hours with the same mac)

if ((dhcp_ret == DHCP_IP_LEASED) || (dhcp_ret == DHCP_IP_CHANGED)) {
#if	USER_DEBUG
		os_printf("\nw5500_dhcp_execute2 b\n");
#endif
		getIPfromDHCP(gWIZNETINFO.ip);
		getGWfromDHCP(gWIZNETINFO.gw);
		getSNfromDHCP(gWIZNETINFO.sn);
		getDNSfromDHCP(gWIZNETINFO.dns);
		gWIZNETINFO.dhcp = NETINFO_DHCP;
		ctlnetwork(CN_SET_NETINFO, (void*) &gWIZNETINFO);
		display_netinfo();
		dhcp_lease_time_rest=getDHCPLeasetime();

@@2. yes, I can find the log in order:

"%d:sock closed1","%d:sock closed2","%d:try to connect to the %d.%d.%d.%d : %d\r\n".

@@3. yes, you can find the any_port++

void ICACHE_FLASH_ATTR w5500_send2()
{
#if	USER_DEBUG
   os_printf("wa70.");
#endif
   os_timer_disarm(&w5500_timer_sending);
   if(connected ==0)
	   return;
   if(data_sending==NULL)
	   return;
// max wait times
   static uint8 connectwaittimes=0;
   connectwaittimes++;
   if(connectwaittimes>30)
   {
		issending=0;
		connectwaittimes=0;
		close(SOCK_TCPS);
#if USER_DEBUG
		os_printf("wa39.");
#endif
		return;
   }


   int32_t ret;
   uint16_t size = 0;
   uint16_t any_port = 	50000;

   uint8 SnSR=getSn_SR(SOCK_TCPS);
#if	USER_DEBUG
   os_printf("wa71:%x.",SnSR);
#endif
   switch(SnSR)
   {
      case SOCK_ESTABLISHED :
		 connectwaittimes=0;
#if USER_DEBUG
		 os_printf("wa0.");
#endif
         if(getSn_IR(SOCK_TCPS) & Sn_IR_CON)	// Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful
         {
#if	USER_DEBUG
			os_printf("%d:Connected to - %d.%d.%d.%d : %d\r\n",SOCK_TCPS, server_ip[0], server_ip[1], server_ip[2], server_ip[3], server_port);
#endif

			setSn_IR(SOCK_TCPS, Sn_IR_CON);  // this interrupt should be write the bit cleared to '1'
#if USER_DEBUG
			os_printf("wa1.");
#endif
         }
#if USER_DEBUG
         os_printf("wa2.");
#endif
         //////////////////////////////////////////////////////////////////////////////////////////////
         // Data Transaction Parts; Handle the [data receive and send] process
         //////////////////////////////////////////////////////////////////////////////////////////////
		 if((size = getSn_RX_RSR(SOCK_TCPS)) > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length
         {
#if USER_DEBUG
			 os_printf("wa3.");
#endif
			if(size > DATA_BUF_SIZE)
				size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array)
			uint8 *rxbuf=(uint8 *)os_zalloc(size);
			ret = recv(SOCK_TCPS, rxbuf, size); // Data Receive process (H/W Rx socket buffer -> User's buffer)
#if USER_DEBUG
			os_printf("wa4.");
#endif
			if(ret <= 0)
			{
				os_free(rxbuf);
		 		rxbuf=NULL;
				return; // If the received data length <= 0, receive failed and process end
			}
#if USER_DEBUG
			os_printf("wa5.");
#endif
			w5500_receive(rxbuf,ret);
#if USER_DEBUG
			os_printf("wa6.");
#endif
         }
#if USER_DEBUG
		 os_printf("wa7.");
#endif
		 ret = send(SOCK_TCPS, data_sending + data_sending_sent, data_sending_len - data_sending_sent); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
#if USER_DEBUG
		 os_printf("wa8.");
#endif
		 if(ret < 0) // Send Error occurred (sent data length < 0)
		 {
#if USER_DEBUG
			os_printf("wa9.");
#endif
			issending=0;
			close(SOCK_TCPS); // socket close
			return;
		 }
#if USER_DEBUG
		 os_printf("wa10. %d,%d,%d\r\n",data_sending_len,data_sending_sent,ret);
#endif
		 data_sending_sent += ret; // Don't care SOCKERR_BUSY, because it is zero.
		 if (data_sending_len <= data_sending_sent)
		 {
			os_printf("\n\th: %u,l: %u\n",system_get_free_heap_size(),data_sending_len);
			data_sending_sent=0;
			data_sending_len=0;
			os_free(data_sending);
			data_sending=NULL;
			led_set();
			http_upload_times=http_upload_times+1;
			http_upload_times_temp=http_upload_times;
			receivei=senti;
#if USER_DEBUG
			os_printf("wa11.");
#endif
			w5500_send();
#if USER_DEBUG
			os_printf("wa12.");
#endif
			return;
		 }
#if USER_DEBUG
		 os_printf("wa13.");
#endif
		 //////////////////////////////////////////////////////////////////////////////////////////////
         break;

      case SOCK_CLOSE_WAIT :
#if	USER_DEBUG
    	   os_printf("%d:sock close wait\r\n", SOCK_TCPS);
#endif
//         if((ret=disconnect(SOCK_TCPS)) != SOCK_OK)
//        	 return ;
#if USER_DEBUG
    	   os_printf("wa30.");
#endif
  		   if(getSn_IR(SOCK_TCPS) & Sn_IR_TIMEOUT)
  		   {
#if USER_DEBUG
  	    	 os_printf("wa31.");
#endif
  			 setSn_CR(SOCK_TCPS,Sn_CR_CLOSE);
  			 while( getSn_CR(SOCK_TCPS) );
  			/* clear all interrupt of the socket. */
  			 setSn_IR(SOCK_TCPS, 0xFF);
  		   }else{
#if USER_DEBUG
  			 os_printf("wa32.");
#endif
        	 setSn_CR(SOCK_TCPS,Sn_CR_DISCON);
  		   }
         break;

      case SOCK_INIT :
#if	USER_DEBUG
    	 os_printf("%d:try to connect to the %d.%d.%d.%d : %d\r\n", SOCK_TCPS, server_ip[0], server_ip[1], server_ip[2], server_ip[3], server_port);
	     os_printf("wa33.");
#endif
    	 if( (ret = connect(SOCK_TCPS, server_ip, server_port)) != SOCK_OK)
    	 {
#if USER_DEBUG
  	    	 os_printf("wa34.");
#endif

    		 return;	//	Try to TCP connect to the TCP server (destination)
    	 }
#if USER_DEBUG
	     os_printf("wa35.");
#endif
         break;

      case SOCK_CLOSED:
#if	USER_DEBUG
	      os_printf("wa36.");
    	  os_printf("%d:sock closed1.", SOCK_TCPS);
#endif
    	  close(SOCK_TCPS);
#if	USER_DEBUG
    	  os_printf("%d:sock closed2.", SOCK_TCPS);
#endif
    	  if((ret=socket(SOCK_TCPS, Sn_MR_TCP, any_port++, 0x00)) != SOCK_TCPS)
    	  {
#if	USER_DEBUG
   	    	 os_printf("wa37.");
#endif
    		  return; // TCP socket open with 'any_port' port number
    	  }
#if	USER_DEBUG
	    	 os_printf("wa38.");
#endif
         break;
      default:
         break;
   }
#if	USER_DEBUG
   os_printf("wa14:%u.",SnSR);
#endif
   os_timer_setfn(&w5500_timer_sending, w5500_send2, NULL);
   os_timer_arm(&w5500_timer_sending, 50, 0);
   return;
}

Hello,

  1. It would be better to check the packets with wireshark. Connect w5500 and PC to Dummy Hub and check on PC. You can download wireshark at Wireshark · Download and it is simple to use.
    By clicking below, you can see all the packets sent and received on the network.


    To see only packets that communicate with your server, write the server ip in the blank. (ip.addr = xxx.xxx.xxx.xxx)

    For the connection to be successful, there should be a syn - syn, ack - ack packet. Only the syn packet will exist in the present situation. Check this out.
    It is also recommended to try the connection process again after issuing the close command.

  2. To check the ARP cache, check the ARP cache table in the server to see if the W5500 ip is set up properly.