sockets-select.c

[root@localhost chapter15]# cat select.c 
/*  Begin as usual with the includes and declarations
    and then initialize inputs to handle input from the keyboard.  */

#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    char buffer[128];
    int result, nread;

    fd_set inputs, testfds;
    struct timeval timeout;

    FD_ZERO(&inputs);//clear inputs fdset
    FD_SET(0,&inputs); //add stdout into inputs fdset

/*  Wait for input on stdin for a maximum of 2.5 seconds.  */

    while(1) {
        testfds = inputs;
        timeout.tv_sec = 2;
        timeout.tv_usec = 500000;

        //result = select(FD_SETSIZE, &testfds, (fd_set *)0, (fd_set *)0, &timeout);
	result = select(FD_SETSIZE, &testfds, (fd_set *)0, (fd_set *)0, NULL);
	
/*  After this time, we test result. If there has been no input, the program loops again.
    If there has been an error, the program exits.  */

        switch(result) {
        case 0:
            printf("timeout\n");
            break;
        case -1:
            perror("select");
            exit(1);

/*  If, during the wait, we have some action on the file descriptor,
    we read the input on stdin and echo it whenever an <end of line>
    character is received,
    until that input is Ctrl-D.  */

        default:
            if(FD_ISSET(0,&testfds)) {
                ioctl(0,FIONREAD,&nread);//FIONREAD,用于获取输入缓冲区的可用字节数
                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;
        }
    }
}

[root@localhost chapter15]# ./select 
f
read 2 from keyboard: f
gds
read 4 from keyboard: gds
dsa
read 4 from keyboard: dsa
hh
read 3 from keyboard: hh

select的效率
当timeout=NULL(或0)时,则阻塞在select。直到testfds变化,
当timeout参数设置>0时,则阻塞在select。直到testfds变化或者timeout超时
当timeout.tv_sec = 0;timeout.tv_usec = 0;时,不会阻塞在select。不管testfds有没变化,进程都会继续执行

select监视标准输入文件-键盘
若result=0,文件无动作
若reasult>0,文件有动作->若nread=0,客户挂掉;若nread>0,客户有输入

ioctl(0,FIONREAD,&nread);
返回文件描述符0的可用数据到nread变量里

     /*int select(int nfds, fd_set *readfds, fd_set *writefds,
                  fd_set *exceptfds, struct timeval *timeout);

       void FD_CLR(int fd, fd_set *set);
       int  FD_ISSET(int fd, fd_set *set);
       void FD_SET(int fd, fd_set *set);
       void FD_ZERO(fd_set *set);

       Three independent sets of file descriptors are watched.  Those listed in readfds will be watched  to  see  if
       characters  become  available  for reading (more precisely, to see if a read will not block; in particular, a
       file descriptor is also ready on end-of-file), those in writefds will be watched to see if a write  will  not
       block,  and  those  in  exceptfds will be watched for exceptions.  On exit, the sets are modified in place to
       indicate which file descriptors actually changed status.  Each of the three file descriptor sets may be spec‐
       ified as NULL if no file descriptors are to be watched for the corresponding class of events.

       Four macros are provided to manipulate the sets.  FD_ZERO() clears a set.  FD_SET() and FD_CLR() respectively
       add and remove a given file descriptor from a set.  FD_ISSET() tests to see if a file descriptor is  part  of
       the set; this is useful after select() returns.

       nfds is the highest-numbered file descriptor in any of the three sets, plus 1.

       timeout  is  an  upper  bound  on  the amount of time elapsed before select() returns.  If both fields of the
       timeval structure are zero, then select() returns immediately.  (This is useful for polling.)  If timeout  is
       NULL (no timeout), select() can block indefinitely.

*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值