#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main()
{
char buffer[128];
int result,nread;
fd_set inputs,testfds;
struct timeval timeout;
FD_ZERO(&inputs);
FD_SET(0,&inputs);
while(1)
{
testfds = inputs;
timeout.tv_sec = 2;
timeout.tv_usec = 500000;
result = select(FD_SETSIZE,&testfds,(fd_set *)NULL,(fd_set *)NULL,&timeout);
switch(result)
{
case 0:
printf("timeout\n");
break;
case -1:
perror("select");
exit(1);
default:
if(FD_ISSET(0,&testfds))
{
ioctl(0,FIONREAD,&nread);
if(nread == 0)
{
printf("keyboard done\n");
exit(0);
}
nread = read(0,buffer,nread);
buffer[nread] = 0;
printf("read %d from keyboard: %s",nread,buffer);
}
break;
}
}
}
void FD_ZERO(fd_set *fdset);
void FD_CLR(int fd,fd_set *fdset);
void FD_SET(int fd,fd_set *fdset);
int FD_ISSET(int fd,fd_set *fdset);
FD_ZERO用于将fd_set初始化为空集合
FD_SET和FD_CLR分别用于在集合中设置和清除由参数fd传递的文件描述符。
FD_ISSET由参数fd指向的文件描述符是由参数fdset指向的fd_set集合中的一个元素,FD_ISSET将返回非0值。FD_ISSET查看某个文件句柄是否被设置了。
select调用用于测试文件描述符集合中,是否有一个文件描述符已处于可读或可写或错误状态,它将阻塞以等待某个文件描述符进入上述这些状态。
select调用返回状态发生变化的描述符总数。失败时它将返回-1并设置errorno来描述错误。
参数nfds指定测试文件描述符数目,测试的描述符范围从0到nfds-1.
用 法: int ioctl(int handle, int cmd,[int *argdx, int argcx]);
功 能: 控制I/O设备 ,提供了一种获得设备信息和向设备发送控制参数的手段。用于向设备发控制和配置命令 ,有些命令需要控制参数,这些数据是不能用read / write 读写的,称为Out-of-band数据。也就是说,read / write 读写的数据是in-band数据,是I/O操作的主体,而ioctl 命令传送的是控制信息,其中的数据是辅助的数据。
FIONREAD :获取接收缓存区中的字节数
运行这个程序时,它会每隔2.5秒打印一个timeout。如果在键盘上敲人字符。它就会从标准输入读取数据并报告敲人的内容。
./select
timeout
hello
read 6 from keyboard:hello
fred
read 5 from keyboard:fred
timeout
CTRL+D
keyboard done