WorkerBee |
02-27-2013 11:04 AM |
Getting O_NONBLCOK to work on Redhat linux TCP C
------------Introduction---------
Hi I am new to this forum, but I look forward to asking and answering questions. I have just recently started doing development on linux. I have taken some classes on linux in the past, but it has been a while. Please bare with me if some of my questions are noobish.
-WB
------------Question-------------
Lately I have been trying to get O_NONBLOCK working on Redhat linux to no success. I am using FNCTL() to turn on O_NONBLOCK right before the initial connection. After the connection I check and read out the ERRNO for debugging purposes. My problem is that I am not getting the expected ERRNO of EAGAIN. I am inconsistently getting back 5, 40, and 11. Is there something I am doing wrong? This is all so I can use KEEPALIVE to reset my connection if a probe times out.
I have listed out snippets my code below:
Connection Function
Code:
long ConnectSocket(long Socket, char *pServerAddress, char Family, ULONG ServerPort )
{
long rc;
struct sockaddr_in ServerAdd;
//Var for O_NONBLOCKING
int flags;
//var to re-set socket's timeout value ~WB
struct timeval timeout;
//creates a variable for KEEPALIVE's optval parm', WB
int optval;
//creates a variable for KEEPALIVE's optlen parm', WB
socklen_t optlen = sizeof(optval);
// INITIALIZE FIELDS
memset( &ServerAdd, 0, sizeof( ServerAdd ) );
ServerAdd.sin_family = Family;
ServerAdd.sin_port = htons( ServerPort );
ServerAdd.sin_addr.s_addr = inet_addr( pServerAddress );
if ( (long) ServerAdd.sin_addr.s_addr == -1)
{
if ( (pHost = s_gethostbyname(pServerAddress))) //does not return NULL
memcpy(&ServerAdd.sin_addr, pHost->h_addr, pHost->h_length);
else
{
if (ConnectRetries == 0 && ErrorsBeforeHandshake == 0)
LogMessage(&LogStruct, ERROR, LOGQUEUE + LOGSCREEN,
"Could not resolve host name\n");
else
LogMessage(&LogStruct, ERROR, LOGSCREEN,
"Could not resolve host name\n");
ConnectRetries++;
CloseSocket( Socket, 0 );
return(-1);
}
}
// DO CONNECT
rc = s_connect( Socket, (struct sockaddr *)&ServerAdd, sizeof( ServerAdd ));
//initialize flags var, WB
flags = fcntl(Socket, F_GETFL, 0);
//turns on O_NONBLOCKING, WB
fcntl(Socket, F_SETFL, flags | O_NONBLOCK);
LogMessage(&LogStruct, INFO, LOGQUEUE + LOGSCREEN,
"right after the initial connection, WB and errno is %d\n", errno);
LogMessage(&LogStruct, INFO, LOGQUEUE + LOGSCREEN,
"right after the initial connection, WB, O_NONBLOCK is %ld", fcntl(Socket,F_SETFL,flags));
if(fcntl(Socket,F_SETFL,flags) < 0)
{
LogMessage(&LogStruct, INFO, LOGQUEUE + LOGSCREEN,
"O_NONBLOCK is not on, errno is %ld", errno);
}
// sets KEEPALIVE parms, WB
optval = 1;
optlen = sizeof(optval);
// turns on KEEPALIVE property on socket, WB
setsockopt (Socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen);
if ( rc == 0)
{
if (ErrorsBeforeHandshake == 0)
LogMessage(&LogStruct, INFO, LOGQUEUE + LOGSCREEN,
"Socket Established id = %ld", Socket);
else
LogMessage(&LogStruct, INFO, LOGSCREEN,
"Socket Established id = %ld", Socket);
ConnectRetries = 0;
Delay(500);
}
else
{
if (ConnectRetries == 0 && ErrorsBeforeHandshake == 0)
LogMessage(&LogStruct, INFO, LOGQUEUE + LOGSCREEN,
"Connection Error rc = %ld (40 = Connection refused by host)", errno);
else
LogMessage(&LogStruct, ERROR, LOGSCREEN,
"Connection Error rc = %ld", errno);
ConnectRetries++;
CloseSocket( Socket, 0 );
}
return( rc );
}
Main
Code:
void R_main(void *arg)
{
long len;
printf("R thread - starting\n");
MainTcpipIndex = TcpipIndex = 0;
// printf("MainTcpipIndex = %d\n", MainTcpipIndex);
while ( fMainShutdown == FALSE )
{
s_MuxWait(5000, "", &hevTcpipBuffAvail[MainTcpipIndex], 0);
if ( hevTcpipBuffAvail[MainTcpipIndex] == 0)
continue;
len = s_recv( lSocket, TcpipRecord[MainTcpipIndex].TcpipBuffer,
sizeof(TcpipRecord[MainTcpipIndex].TcpipBuffer));
LogMessage(&LogStruct, INFO, LOGQUEUE + LOGSCREEN,
"right after the recv(), WB and len is %d\n", len);
if (len < 0 && errno != 11 || len == 0) //0 = connection broken by host
{
if (errno == ETIMEDOUT)
{
LogMessage(&LogStruct, INFO, LOGQUEUE + LOGSCREEN, "keepalive probe timed out, WB\n");
}
ReceiveError = errno;
hevReceiveError = 1;
printf("R_main - set hevReceiveError ON\n");
//LogMessage( pMpsStructMain->pLogStruct, ERROR, LOGQUEUE + LOGSCREEN,
//"R_main - set hevReceiveError ON" );
pthread_exit(NULL);
}
if (len == -1 && errno == 11)
{
LogMessage(&LogStruct, INFO, LOGQUEUE + LOGSCREEN, "Caught the O_NONBLOCKING\n");
len = 0;
continue;
}
// Record Length
TcpipRecord[MainTcpipIndex].ulTcpipBufLen = len;
//printf("Received message on index %d\n", MainTcpipIndex);
// Tell T Thread we have a message
hevTcpipBuffUsed[MainTcpipIndex] = 1;
hevTcpipBuffAvail[MainTcpipIndex] = 0;
// Maintain Index
if ( ++MainTcpipIndex >= MAX_TCPIP_BUFFS )
MainTcpipIndex = 0;
}//end while
}
|