Home/Support/Support Forum/NetOs 7.5, NAIpSetKaInterval not working - Connect ME
Welcome to Digi Forum, where you can ask questions and receive answers from other members of the community.

NetOs 7.5, NAIpSetKaInterval not working - Connect ME

0 votes
hello,

I'm trying to develop a simple TCP server application, my application allows 4 TCP clients simultaneously.

In order to check possible "half open" connections, i'm using "non blocking" sockets and "keepalive" option is set to my server socket.

I'm adjusting TCP keealive interval with NAIpSetKaInterval before creating my sockets.

My application works fine if i close sockets from the client side. The problem starts when i unplug the computer network's cable while sending data over socket, in this situation ( half open socket) i expected to catch some error with recv, but i'm not! So it takes to long to detect that the connection was closed.

I also tried to use wireShark in order to find some "keepAlive" packets, i can see some with a long time between them ( bigger than the interval defined with NAIpSetKaInterval )

Please take a look in my code:

################## Server socket creation----
....
unsigned short keepInterval = 10;
NAIpSetKaInterval(keepInterval);

memset(br,0,sizeof(br));

if((serverSocketDescriptor = socket(PF_INET,SOCK_STREAM,0)) < 0){
NAReset();
}

if(setsockopt(serverSocketDescriptor , SOL_SOCKET, SO_NONBLOCK, (char *)&amp;block, sizeof(block)) < 0){
closesocket(serverSocketDescriptor);
NAReset();
}

if(setsockopt(serverSocketDescriptor , SOL_SOCKET, SO_KEEPALIVE, (char *)&amp;block, sizeof(block)) < 0){
closesocket(serverSocketDescriptor);
NAReset();
}


serverSocket.sin_family = AF_INET;
serverSocket.sin_port = TCP_PORT;
serverSocket.sin_addr.s_addr = INADDR_ANY;

if (bind(serverSocketDescriptor, (struct sockaddr*)&amp;serverSocket, sizeof(serverSocket)) == SOCKET_ERROR){
socketclose(serverSocketDescriptor);
serverSocketDescriptor=-1;
NAReset();
}

if (listen(serverSocketDescriptor, listenBacklog)<0){
socketclose(serverSocketDescriptor);
NAReset();
}

##################Server accepts

...
while(1)
{
//Checks connections
for (i=0; i<NTHREADS; i++){
brPtr = &amp;(br);
if(brPtr->status){
threadName = br->threadName;
status = tx_thread_info_get(&amp;(brPtr->tx_thread), &amp;threadName,&amp;state,&amp;run_count, &amp;priority, &amp;preemption_threshold, &amp;time_slice, &amp;next_thread,&amp;suspended_thread);
if( (status != TX_SUCCESS) || ((status == TX_SUCCESS) &amp;&amp; (state == TX_TERMINATED )) ){
tx_thread_delete(&amp;brPtr->tx_thread);
close(brPtr->clientSock);
memset(brPtr,0,sizeof(bridgeObj));
if (nthreads > 0)
nthreads--;
}
}
}
//TX_THREAD_ERROR
//Accepts client connection request
if ((ret = accept(serverSocketDescriptor, (struct sockaddr*)&amp;clientSocket, &amp;addrLen))>0){
if (nthreads >= NTHREADS){
closesocket(ret);
continue;
}

if(setsockopt(ret , SOL_SOCKET, SO_KEEPALIVE, (char *)&amp;block, sizeof(block)) < 0){
closesocket(serverSocketDescriptor);
NAReset();
}

// addr = clientSocket.sin_addr.s_addr;
// clientSocketDescriptor = retVal;
// printf("Connected to client %ld.%ld.%ld.%ld; remote port %d\n",
// addr>>24, (addr>>16)&amp; 0xff, (addr>>8)&amp;0xff, addr&amp;0xff, clientSocket.sin_port);

//Now is time to found one available thread slot
for(s=0;s<NTHREADS;s++){
brPtr = &amp;(br[ s ]);
if(brPtr->status==0){
brPtr->status=1;
break;
}
}
if(s==NTHREADS){
NAReset();
}

brPtr->clientSock = (SOCKET)ret;
sprintf(brPtr->threadName, "Sock_%d", s);
for(i=0;i<5;i++){
ret = tx_thread_create (&amp;(brPtr->tx_thread), /* control block for root thread*/
brPtr->threadName, /* thread name*/
dataPipe, /* entry function*/
(ULONG)s, /* parameter*/
brPtr->stackP, /* start of stack*/
sizeof(brPtr->stackP), /* size of stack*/
BSP_MEDIUM_PRIORITY, /* priority*/
BSP_MEDIUM_PRIORITY, /* preemption threshold */
3, /* time slice threshold*/
TX_AUTO_START); /* start immediately*/
if (ret==TX_SUCCESS){
nthreads++;
break;
//printf("Data Pipe Created, Thread ID %s\n\n", dyn_name);
}
}
if (ret!=TX_SUCCESS){
//if couldn't create thread
//netosFatalError ("Unable to create root thread", 1, 1);
closesocket(serverSocketDescriptor);
NAReset();
}
tx_thread_relinquish();
}
}// while(1)

############## dataPipe thread
....
while ( 1 ) {
// section in code to check to see if call is non blocking - break on if retval statement
// receive data from client socket
getErrno();
getErrno();
//retVal = recv(clientSocketDescriptor,&amp;recByte,1,socketPacketAttributes);
ret = recv(brPtr->clientSock,(char*)brPtr->bufIn,sizeof(brPtr->bufIn),0);

/* Socket error? */
if(ret < 0){
rc = getErrno();
if(rc != EAGAIN){
socketclose(brPtr->clientSock);
aux = tx_mutex_put(&amp;appMutex);
tx_thread_terminate(tx_thread_identify());
return;
}
}else if(ret == 0){
// connection terminated
socketclose(brPtr->clientSock);
aux = tx_mutex_put(&amp;appMutex);
tx_thread_terminate(tx_thread_identify());
return;
}

for(k=0;k<ret;k++){
....

Please help me! I'm really can't figure out what is happening!

Thanks in advance,
Marcio
asked Sep 5, 2011 in NET+OS by Oicram New to the Community (4 points)

Please log in or register to answer this question.

2 Answers

0 votes
Hi i had the same problem, and i find out that keep alive is not so much working on NET+OS. How ever rewrite you app to use blocked reading and use select for timeout the connection. I post some example to this thread
http://forums.digi.com/support/forum/viewthread_thread,8617

Jirka
answered Sep 6, 2011 by kubiajir Community Contributor (61 points)
0 votes
You might also want to reduce MSL via the API NaIpSetTcpMsl. Default is 2 minutes. I believe the parameter is in seconds.
answered Nov 15, 2011 by dakotas_dad Veteran of the Digi Community (694 points)
...