Nikhil
Nikhil

Reputation: 586

Select () function is getting timed out even after the socket has data to read in linux C

I am facing a problem with select.

Below is my code snippet for receiving the data (server side):

int tcpip_receive_data (int sockfd, char *recv_buffer, int buffer_len, int flags, long sec_timeout)
{
 int ret = 0 ;
 fd_set fdsock ;
 struct timeval timeout = {0x00,} ;

 if ((sockfd < 0) || !(recv_buffer) || !(buffer_len))
 {
  return FAIL ;
 }

 if (sec_timeout > 0)
 {
  /* the socket to monitor */
  FD_ZERO (&fdsock) ;
  FD_SET ((unsigned int) sockfd, &fdsock) ;

  /* set a timeout */
  timeout.tv_sec = sec_timeout ;
  timeout.tv_usec = 0 ;

  /* now check whether some data is there or not */
  if ((ret = select (sockfd + 1, &fdsock, NULL, NULL, &timeout)) <= 0)
  {

   printf ("ERROR: Select() retValue[%d] for SockID[%d]%s:%d", ret, sockfd, __FILE__, __LINE__) ;
   return FAIL ; 
  }
  else if (ret == 0) 
  {
   printf ("ERROR: Select timed out for SockID[%d]- %s:%d", sockfd, __FILE__, __LINE__) ;
   return FAIL ;
  }

 }
 return (recv (sockfd, recv_buffer, buffer_len, flags)) ;
}

Below is my code snippet for sending the data ( client side):

int main ( int argc, char **argv )
{
                struct sockaddr_in sock_client;
                char ip_address [IP_ADDR_LEN] = {0,};
                char filename [MAXSTR] = {0,};
                int port = 0;
                int sock_fd = 0;
                FILE *input_fp = NULL;
                FILE *output_fp = NULL;
                int len = 0, ret = 0;
                char data [ BUF_SIZE ] = {0,};
                char recv_buffer [ BUF_SIZE ] = {0,};
                struct hostent *host;

                printf ("%d\n", argc);
                if ( argc != 4 ) 
                {   
                        fprintf ( stdout, "<Usage> ./wsp_client <IPAddress> <Port> <DataFilename>\n" );
                        return 0;
                }   

                strcpy ( ip_address ,argv[1] );
                port = atoi ( argv[2] );
                strcpy ( filename, argv[3] );

                printf ("%s:%d:%s\n", ip_address, port, filename );

                if ( ( input_fp = fopen ( filename, "rb" ) ) == NULL )
                {   
                        perror ("Input file fopen:");
                        return 0;
                }   

                if ( ( output_fp = fopen ( "./read_data", "wb" ) ) == NULL )
                {   
                        perror ("Outuput fopen:");
                        return 0;
                }   

                while ( !feof(input_fp) )
                {   
                                if ( ( ret = fread ( data, 1, BUF_SIZE, input_fp ) ) < 0 ) 
                                {   
                                        printf ("fread failed, ferror=[%d] feof=[%d]", ferror (stdin), feof(input_fp));

                                        break ;
                                }
                                len += ret;
                }

                fwrite ( data, sizeof (char), len, output_fp );
                fclose ( input_fp );
                fclose ( output_fp );

                //create a scoket.
                if ( ( sock_fd = socket ( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
                {
                        perror ( "Socket Error:" );
                        return 0;
                }

                //form the structure.
                host = gethostbyname(ip_address);
                sock_client.sin_family = AF_INET;
                sock_client.sin_port = htons (port);
                sock_client.sin_addr = *((struct in_addr *)host->h_addr);

                //connect
                printf ( "Connecting to port %d\n", port );
                if ( connect ( sock_fd, (struct sockaddr *) &sock_client, sizeof ( sock_client ) ) < 0 )
                {
                        perror ( "connect:" );
                        return 0;
                }

                printf ("Connection Established\n");

                printf ("Sending data of lenght:%d\n", len);
                if ( ( ret = send ( sock_fd, data, len, 0 ) ) < 0 )
                {
                        perror ("send:");
                        return 0;
                }
                printf ("Sent data of lenght:%d\n", len);

                recv (sock_fd, recv_buffer, BUF_SIZE, 0);

                close ( sock_fd );
}

The problem is the client program which i have written is able to send the data but the server is not able to receive the data. But the with other client program(actually a tool) I am able to send data and the server is able to receive the data and process the data received.

And from the tcpdump, there has been a connection established, and the client have sent data, and the server has acknowledged it( Please check the Wrieshark pasted below ). But the server is giving me the logs saying that timeout occurred.

enter image description here

Why is select is not waking up when the data present in the socket. Why it is getting timedout.

Please help me to sort the problem.

Upvotes: 2

Views: 2754

Answers (1)

David Schwartz
David Schwartz

Reputation: 182743

The other side is not sending you any data. Whatever data you're sending it, it isn't sufficient to cause it to send you a reply. Your select is timing out because the specified time, 30 seconds, has passed.

Upvotes: 4

Related Questions