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

即使缓冲区中有数据,select()也会超时,c,select-function,C,Select Function,这个程序(我相信)是select()的直接应用程序(在Debian for ARM上)。 XBeedDevice指向一个串行端口。串行端口存在,ic连接到设备 问题是,select()返回0,即使接收到数据。我临时注释掉了最后一个“else”,程序打印TIMEOUT,然后是远程设备返回的字符串 int main( int argc, char **argv ) { int fd, c, res, n; struct termios oldtio, newtio; char buf[2

这个程序(我相信)是select()的直接应用程序(在Debian for ARM上)。 XBeedDevice指向一个串行端口。串行端口存在,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 );
}
int main(int argc,char**argv){
int-fd,c,res,n;
结构termios oldtio、NERTIO;
char buf[255]={0};
fd_集输入;
结构timeval超时;
//定义超时
timeout.tv_sec=5;
timeout.tv_usec=0;
fd=打开(xBeedDevice,O|RDWR | O|NOCTTY);
如果(fd<0){
perror(XBEEDEVICE);
返回(-1);
}
tcgetattr(fd,&oldtio);/*保存当前端口设置*/
bzero(&newtio,sizeof(newtio));
newtio.c|cflag=CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag=IGNPAR;
newtio.c_of lag=0;
/*设置输入模式(非规范、无回声等)*/
newtio.c_lflag=0;
newtio.c_cc[VTIME]=0;/*未使用字符间计时器*/
newtio.c_cc[VMIN]=2;/*在收到2个字符之前阻止读取*/
tcflush(fd,TCIFLUSH);
tcsetattr(fd、TCSANOW和newtio);
//在1秒内发送+++将XBee设置为命令模式
printf(“发送+++\n”);
写入(fd,“+++”,3);
n=选择(fd、输入和空、空和超时);
if(n<0)
printf(“select()失败\n”);
else如果(n==0)
printf(“超时\n”);
//否则{
res=读取(fd,buf,250);
buf[res]=0;
printf(“收到:%s\n”,buf);
//}
tcsetattr(fd、TCSANOW和oldtio);
返回(0);
}

您应该初始化
输入
以包含
fd
。这是通过
FD_ZERO
FD_SET
宏完成的:

FD_ZERO(&input);
FD_SET(fd, &input);
每次调用
select
之前都必须执行此操作


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

,您应该初始化
输入
以包含
fd
。这是通过
FD_ZERO
FD_SET
宏完成的:

FD_ZERO(&input);
FD_SET(fd, &input);
每次调用
select
之前都必须执行此操作


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

,您应该为问题添加更多标记。Stackoverflow有一个很好的系统来通知人们他们最喜欢的标签,所以如果你添加更多相关标签,其他人会更容易找到你的问题……你应该在你的问题中添加更多标签。Stackoverflow有一个很好的系统来通知人们他们最喜欢的标签,所以如果你添加更多相关标签,其他人会更容易找到你的问题…谢谢,我今晚会试试。我尝试了fd+1(但不是fd_ZERO()或fd_SET()),这没有什么区别。我添加了fd_ZERO()和fd_SET()调用,并将“fd”更改为fd+1,现在它可以工作了。非常感谢你!谢谢你,我今晚试试。我尝试了fd+1(但不是fd_ZERO()或fd_SET()),这没有什么区别。我添加了fd_ZERO()和fd_SET()调用,并将“fd”更改为fd+1,现在它可以工作了。非常感谢你!