简体   繁体   English

套接字无法正常工作的文件描述符

[英]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. 每当我向Stdin写东西时,它都可以工作,但它不适用于套接字。 It's not able to enter the loop for Socket. 它无法进入Socket循环。 I am new to socket programming. 我是socket编程的新手。

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);
    }
  }
}

It appears that you don't understand how the nfds argument to select() is used. 看来你不明白如何使用select()nfds参数。 The man page addresses this explicitly: 手册页明确地解决了这个问题:

The first nfds descriptors are checked in each set; 在每组中检查第一个nfds描述符; ie, the descriptors from 0 through nfds-1 in the descriptor sets are examined. 即,检查描述符集中从0到nfds-1的描述符。 (Example: If you have set two file descriptors "4" and "17", nfds should not be "2", but rather "17 + 1" or "18".) (示例:如果您设置了两个文件描述符“4”和“17”,则nfds不应为“2”,而应为“17 + 1”或“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);
    }

 }
  1. FDZERO must go before FDSET inside the loop FDZERO必须在循环内的FDSET之前
  2. select(2, ...) should be select(highest filedescriptor +1, ...). 应选择select(2,...)(最高文件描述符+1,...)。
  3. when select returns you should check for negative value in case of errors 当select返回时,您应该在出现错误时检查负值
  4. you should consider using pselect instead of select. 你应该考虑使用pselect而不是select。
  5. Clear tv before you reinitialize it. 在重新初始化之前清除电视。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM