LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Getting O_NONBLCOK to work on Redhat linux TCP C (https://www.linuxquestions.org/questions/linux-newbie-8/getting-o_nonblcok-to-work-on-redhat-linux-tcp-c-4175451928/)

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
}


chrism01 02-27-2013 06:48 PM

I'd recommend using the Report button to ask the Mods to move this to the Programming forum.


All times are GMT -5. The time now is 02:32 AM.