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 *)&block, sizeof(block)) < 0){
closesocket(serverSocketDescriptor);
NAReset();
}
if(setsockopt(serverSocketDescriptor , SOL_SOCKET, SO_KEEPALIVE, (char *)&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*)&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; istatus){
threadName = br->threadName;
status = tx_thread_info_get(&(brPtr->tx_thread), &threadName,&state,&run_count, &priority, &preemption_threshold, &time_slice, &next_thread,&suspended_thread);
if( (status != TX_SUCCESS) || ((status == TX_SUCCESS) && (state == TX_TERMINATED )) ){
tx_thread_delete(&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*)&clientSocket, &addrLen))>0){
if (nthreads >= NTHREADS){
closesocket(ret);
continue;
}
if(setsockopt(ret , SOL_SOCKET, SO_KEEPALIVE, (char *)&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
",
// addr>>24, (addr>>16)& 0xff, (addr>>8)&0xff, addr&0xff, clientSocket.sin_port);
//Now is time to found one available thread slot
for(s=0;sstatus==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 (&(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
", 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,&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(&appMutex);
tx_thread_terminate(tx_thread_identify());
return;
}
}else if(ret == 0){
// connection terminated
socketclose(brPtr->clientSock);
aux = tx_mutex_put(&appMutex);
tx_thread_terminate(tx_thread_identify());
return;
}
for(k=0;k