[En-Nut-Discussion] TCP state machine reset

alister alister at qbroadcast.co.uk
Wed Nov 5 10:26:54 CET 2014


Hi All,

I am using an Ethernut 1.3 board as a TCP server.

It opens a socket for one client, and the receive timeout is set to 2 seconds so
I can send heartbeat messages every 15 seconds if there is no other traffic.

This works fine, until the far end disconnects. On reconnection, I am unable to
make the timeout work, so the TCP receiver hangs until a message comes in with the
result that my heartbeat messages do not go out.

Maybe I should not close the socket?

I would be very interested to know if there is an easy way to fix this because
I suspect I am doing something nooby closing and reopening the socket which perhaps
is not the correct way to do this.

Here is the main loop.


int main(void)
{
    int i,ctr, msg_len;
	int num, retval, inbufcnt;
	u_long tmo=2000;
	static u_short mss=1460;
	int errors;
  
     /*
     * Initialize the uart device.
     */
    u_long baud = 9600;
    NutRegisterDevice(&DEV_CONSOLE, 0, 0);
    uart = fopen("uart0", "r+b");

    _ioctl(_fileno(uart), UART_SETSPEED, &baud);

    freopen("uart0", "w+b", stdout);
    freopen("uart0", "r+b", stdin);
	
   // RS422

    if (NutRegisterDevice(&devUsartAvr1,1,0)) // base 1 irq 0
	{
		printf("Usart fail");
		  NutSleep(3000);
 
	}
  
	uart1 = fopen(devUsartAvr1.dev_name, "r+");

	setup_422baud();

	LcdInit();

    /*
     * Load configuration from EEPROM - and set defaults if the
     * configuration is not valid (after firmware update)
     */
    if (NutNetLoadConfig("eth0"))
	{
		memcpy(confnet.cdn_mac, mac, sizeof(confnet.cdn_mac));
     /*
      * Set correct Magic cookie. This is vital on broken/empty eeprom configuration.
      */
		memcpy(confnet.cd_name, "eth0", sizeof(confnet.cd_name));

		confnet.cdn_ip_addr = inet_addr(MYIP);
		confnet.cdn_cip_addr = inet_addr(MYIP);
		confnet.cdn_ip_mask = inet_addr(MYMASK);
		confnet.cdn_gateway = inet_addr(MYGATEWAY);

		printf("Loading default values and storing to EEPROM\r\n");
		NutNetSaveConfig();
    }

 
    /*
     * Register Ethernet controller. RTL port registers at 0x8300, irq 5, or 0,0
for fixed
     */
    if (NutRegisterDevice(&devEth0, 0x8300, 5))
        puts("Registering device failed");
   /*
    * LAN configuration using EEPROM values. NutNetIfConfig() calls inside
NutNetSaveConfig().
    * It will remove the gateway IP address, if it's outside of our network.
    */
    NutNetIfConfig("eth0", confnet.cdn_mac, confnet.cdn_ip_addr,
confnet.cdn_ip_mask); /*configure Ethernet*/

    /*
     * Add optional default route. Add gateway.
     */
    if (GATEWAY && confnet.cdn_ip_addr && confnet.cdn_gateway) {
        NutIpRouteAdd(0, 0, confnet.cdn_gateway, &devEth0);
    }

    /*print current network parameters*/
    PrintNetworkParams();
   /*
     * Start thread for HB timer
     */
    NutThreadCreate("HB_Timer", HB_timer, 0, 64); // stack size
    NutSleep(100);

    /*
     * Start  server threads.
     */
  	NutThreadCreate("PCU", PCUThread, NULL, 64);

   NutSleep(100);
    /*
     * And main program routine
     */

    NutThreadSetPriority(200);         /* was 254 now 200. aw. smallest priority
on main program*/
   // RS422
 
// 	NutThreadCreate("LCD", LCDThread, NULL, 64); resets it!!!

   NutSleep(100);

    printf("\r\nRunning...\r\n");
    /*
     * Main program 
     */
	errors=0;
    /*
     * Now loop endless for connections.  */
    
	for (;;) 
	{
      /*
       * Create a socket and listen for a client.
       */
		sock = NutTcpCreateSocket();
		NutTcpSetSockOpt(sock,SO_RCVTIMEO, &tmo, sizeof(tmo));
		NutTcpSetSockOpt(sock,TCPOPT_MAXSEG, &mss, sizeof(mss));
		

		if (NutTcpAccept(sock, TCPport)!=0) continue;
 
      /*
       * Open a stdio stream assigned to the connected socket.
       */
		TCPStream = _fdopen((int) sock, "r+b");
		TCPconnected = 1;
		while (errors==0)
		{
 			errors+=get_Sony_cmd(&TCPconnected); // This reads and sends messages, and
should timeout 2 secs if not busy
			if (errors)
			{
				retval=NutTcpDeviceIOCtl(sock,IOCTL_GETINBUFCOUNT,&inbufcnt);
				printf("Q rv=%x in=%x ",retval,inbufcnt);
			}
	  
		} // errors=0
     /*
       * Close the stream. as errors!
       */
		TCPconnected = 0;
		fclose(TCPStream);

      /*
       * Close our socket.
       */
		NutTcpCloseSocket(sock);
		errors=0;  // try again
    }
	return 0;
}

Regards/Greetings,
Alister


More information about the En-Nut-Discussion mailing list