sockets-select.c

来源:互联网 发布:flux软件怎么恢复 编辑:程序博客网 时间:2024/05/20 05:09

[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 fread 2 from keyboard: fgdsread 4 from keyboard: gdsdsaread 4 from keyboard: dsahhread 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.*/


原创粉丝点击