Anand Dhandhania
Anand Dhandhania

Reputation: 3

File Descriptor for socket not working

Here is the code i am using. Whenever i write something to the Stdin, it works, but it is not working for socket. It's not able to enter the loop for Socket. I am new to socket programming.

void HandleConnection(int socket)
{
  fd_set rfd;
  struct timeval tv;
  int retval;

  printf("%d",socket);
  MakeNonBlocking(socket);

  /* Watch stdin (fd 0) to see when it has input. */
  FD_ZERO(&rfd);

  while(1)
  {
    FD_SET(STDIN, &rfd);
    FD_SET(socket, &rfd);

    /* Wait up to five seconds. */
    tv.tv_sec = 50;
    tv.tv_usec = 0;

    retval = select(2, &rfd,NULL, NULL, &tv);
    if(retval == 0)
    {
        printf("No data within fifty seconds.\n");
        exit(1);
    }
    if(FD_ISSET(socket,&rfd))
    {
        printf("socket wala\n");
        recieve_message(&socket);
        send_message(&socket);
    }
    if(FD_ISSET(STDIN,&rfd))
    {
        printf("stdin wala\n");
        recieve_message(&socket);
        send_message(&socket);
    }
  }
}

Upvotes: 0

Views: 279

Answers (2)

Barmar
Barmar

Reputation: 780655

It appears that you don't understand how the nfds argument to select() is used. The man page addresses this explicitly:

The first nfds descriptors are checked in each set; i.e., the descriptors from 0 through nfds-1 in the descriptor sets are examined. (Example: If you have set two file descriptors "4" and "17", nfds should not be "2", but rather "17 + 1" or "18".)

So here is how you should rewrite your code.

int maxfd = (socket > STDIN ? socket : STDIN) + 1; /* select() requires the number of FDs to scan, which is max(fds)+1 */

while(1){

  FD_ZERO(&rfd); /* This needs to be done each time through the loop */
  /* Watch stdin (fd 0) to see when it has input. */
  FD_SET(STDIN, &rfd);
  FD_SET(socket, &rfd);

  /* Wait up to five seconds. */
  tv.tv_sec = 50;
  tv.tv_usec = 0;

  retval = select(maxfd, &rfd,NULL, NULL, &tv);
  if(retval == 0)
    {
      printf("No data within fifty seconds.\n");
      exit(1);
    }
  if(retval == -1) /* Check for error */
    {
      perror("Error from select");
      exit(2);
    }
  if(FD_ISSET(socket,&rfd))
    {
      printf("socket wala\n");
      recieve_message(&socket);
      send_message(&socket);
    }
  if(FD_ISSET(STDIN,&rfd))
    {
      printf("stdin wala\n");
      recieve_message(&socket);
      send_message(&socket);
    }

 }

Upvotes: 1

Devolus
Devolus

Reputation: 22074

  1. FDZERO must go before FDSET inside the loop
  2. select(2, ...) should be select(highest filedescriptor +1, ...).
  3. when select returns you should check for negative value in case of errors
  4. you should consider using pselect instead of select.
  5. Clear tv before you reinitialize it.

Upvotes: 1

Related Questions