c - 即使缓冲区中有数据,select() 也会超时

标签 c select-function

这个程序(我相信)是 select() 的直接应用(在 Debian for ARM 上)。 XBEEDEVICE 指向串行端口。串行端口存在并且 ic 连接到设备。

问题是,即使接收到数据,select() 也会返回 0。我暂时注释掉了最后一个'else',程序打印出TIMEOUT,然后是远程设备返回的字符串。

int main( int argc, char **argv ) {
  int fd, c, res, n;
  struct termios oldtio, newtio;
  char buf[255] = {0};

  fd_set input;
  struct timeval timeout;

  // define timeout
  timeout.tv_sec = 5;
  timeout.tv_usec = 0;

  fd = open( XBEEDEVICE, O_RDWR | O_NOCTTY );
  if( fd < 0 ){
    perror( XBEEDEVICE );
    return( -1 );
  }

  tcgetattr( fd, &oldtio ); /* save current port settings */
  bzero( &newtio, sizeof( newtio ));
  newtio.c_cflag = CRTSCTS | CS8 | CLOCAL | CREAD;
  newtio.c_iflag = IGNPAR;
  newtio.c_oflag = 0;

  /* set input mode (non-canonical, no echo,...) */
  newtio.c_lflag = 0;

  newtio.c_cc[VTIME]    = 0;   /* inter-character timer unused */
  newtio.c_cc[VMIN]     = 2;   /* blocking read until 2 chars received */

  tcflush( fd, TCIFLUSH );
  tcsetattr( fd, TCSANOW, &newtio );

  // Sending +++ within 1 second sets the XBee into command mode
  printf( " Sending +++\n" );
  write( fd, "+++", 3 );

  n = select( fd, &input, NULL, NULL, &timeout );

  if( n < 0 )
    printf( "select() failed\n" );
  else if( n == 0 )
    printf( "TIMEOUT\n" );
  //else{
    res = read( fd, buf, 250 );
    buf[res] = 0;
    printf( "Received: %s\n", buf );
  //}
  tcsetattr( fd, TCSANOW, &oldtio );

  return( 0 );
}

最佳答案

您应该初始化input 以包含fd。这是通过 FD_ZEROFD_SET 宏完成的:

FD_ZERO(&input);
FD_SET(fd, &input);

这必须在每次调用 select 之前完成。

select 的第一个参数应该是 fd+1。它是要检查的范围内的文件描述符的数量。由于范围内的最大(且唯一)描述符编号为 fd,而最小值始终为 0,因此所讨论的编号为 fd+1

关于c - 即使缓冲区中有数据,select() 也会超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14845705/

相关文章:

c++ - 边界矩形碰撞测试?

c - 这个AVL平衡代码有什么问题?

c - 即使在无法访问的 ICMP 端口上,select() 也会超时 3 秒

c - 套接字上的 select() (问题)

c - select() 仅返回正值一次

c# - 从 C 移植到 C# 时是否需要 __W64?

c - 如何从 htop 隐藏 system() 函数中传递的系统调用

c - C语言在linux上的串行编程

c - 使用 sleep 和 select 信号

c - 管道和 select() 有问题