本文介绍了阻塞select()从多个插座的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的Unix / C的问题。

Unix/C question here.

我有我试图轮询周期数据的多个插座。我不想选择无限期地等待,所以我有一个适当的超时时间,我在一个循环中运行。我发现,一旦一个套接字准备好读,它总是准备好读。正如,我不能有选择去的时候没有从任意插座的读取数据睡觉。

I have multiple sockets that I am trying to poll for periodic data. I don't want select to wait indefinitely so I have a timeout in place and I'm running in a loop. I have found that once a socket is ready to read, it is always ready to read. As in, I cannot have select go to sleep when there is no data to be read from any of the sockets.

for (i = 0; i < n_connections; i++) {
  FD_SET( sockfd[i], &master );
  if (sockfd[i] > fdmax)
    fdmax = sockfd[i];
  }

for(;;) {
  int nready = 0;
  timeout.tv_sec  = 1;
  timeout.tv_usec = 0;
  read_fds = master;
  if ( (nready = select(fdmax+1, &read_fds, NULL, NULL, NULL)) == -1 ) {
    fprintf( stderr, "Select Error\n" );
    return FAILURE;
  }
  printf( "Number of ready descriptors: %d\n", nready );

  for (i = 0; i <= fdmax; i++) {
    if (FD_ISSET(i, &read_fds)) {
      if (( nbytes = recv(i, buf, sizeof(buf), 0)) <= 0 ) {
        if (nbytes == 0) {
          //connection closed
          printf("Socket %d hung up\n", i );
        }
        else {
          fprintf( stderr, "Recv Error %d\n", nbytes);
        }
      }
    else {
      printf( "Data Received on %d: %s\n", i, buf );
    }
  }
} // end file descriptor loop

看来,我的第一次读取后,1秒超时不再适用,插座始终是准备好读,即使有可用0字节。我怎样才能选择睡觉,直到数据进来(为一秒,或通过切换最后一个参数为NULL,无限期地等待数据来在插座上的?)

It seems that after my first read, the 1 second timeout no longer applies and the socket is always "ready to read", even if there are 0 bytes available. How can I get select to sleep until data comes in (for the one second, or by switching the final argument to NULL, indefinitely waiting for data to come in on the socket?)

输出:

Number of Ready Descriptors: 2
Data Received on 4: GreetingsChap
Data Received on 5: HiMatengsChap
Loop...
Number of Ready Descriptors: 2
Socket 4 hung up
Socket 5 hung up
Loop...
Number of Ready Descriptors: 2
Socket 4 hung up
Socket 5 hung up
Loop...

感谢您,

请注意:code更新为清晰起见
更新基于@yvesBraumes建议 - 仍然无法正常工作

Note: Code updated for clarityUpdated based on @yvesBraumes suggestions - still doesn't work.

推荐答案

如果您发现该连接关闭,从FD集删除插座,否则选择是要举报他们( 4号插座挂了)..选择是不是边沿触发,如果你不处理该事件,这将再次报告。

If you detect that a connection is closed, remove the socket from the fd set, otherwise select is going to report them (Socket 4 hung up).. select is not edge triggered, if you don't handle the event, it's going to report it again.

这篇关于阻塞select()从多个插座的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-12 15:14