0

これが私が使用しているコードです。Stdinに何かを書き込むたびに機能しますが、ソケットでは機能しません。ソケットのループに入ることができません。私はソケットプログラミングが初めてです。

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

2 に答える 2

1

nfds引数 toの使用方法を理解していないようですselect()。manページはこれに明示的に対処しています:

各セットで最初の nfds 記述子がチェックされます。つまり、記述子セットの 0 から nfds-1 までの記述子が調べられます。(例: 2 つのファイル記述子 "4" と "17" を設定した場合、nfds は "2" ではなく、"17 + 1" または "18" にする必要があります。)

したがって、コードをどのように書き直す必要があるかを次に示します。

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

 }
于 2013-05-12T10:59:55.390 に答える
1
  1. FDZERO は、ループ内で FDSET の前に移動する必要があります
  2. select(2, ...) は select(最上位のファイル記述子 +1, ...) にする必要があります。
  3. select が返されたときに、エラーが発生した場合に負の値をチェックする必要があります
  4. select の代わりに pselect の使用を検討する必要があります。
  5. 再初期化する前にテレビをクリアしてください。
于 2013-05-12T11:00:46.840 に答える