这个程序(我相信)是 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_ZERO
和 FD_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/