[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