select函数

来源:百度文库 编辑:神马文学网 时间:2024/04/27 16:19:36
关于select函数:
其函数原型为:
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct tim *timeout);
此函数的功能是由内核检测在timeout时间内,是否有readfds,writefds,exceptfds三个句柄集(file descriptors)里的某个句柄(file descriptor)的状态符合寻求,即readfds句柄集里有句柄可读或writefds句柄集里有可写或exceptfds句柄集里有例外发生,任何一个有变化函数就立即返回,返回值为timeout发生状态变化的句柄个数。
n是所有readfds,writefds,exceptfds三个句柄集(file descriptors)里编号最大值加1。比如:要检测两个socket句柄fd1和fd2在timeout时间内是否分别可读和可写就可以这样:
先把两个句柄集(file descriptors)清零:
        FD_ZERO (&readfds);
        FD_ZERO (&writefds);
然后把fd1加入读检测集:
        FD_SET (fd1, &readfds);
然后把fd2加入写检测集:
        FD_SET (fd2, &writefds);
再给timeout设置值,timeout是这样的一个结构:
              struct tim {
                  long    tv_sec;        
                  long    tv_usec;       
              };
你可以这样赋值:
        timeout.tv_sec=1;
        timeout.tv_uec=0;
表示检测在1秒钟内是否有句柄状态发生变化。
如果有句柄发生变化,就可以用FD_ISSET检测各个句柄,比如:
                FD_ISSET (fd1, &readfds);//检测是否fd1变成可读的了
                FD_ISSET (fd2, &writefds);//检测是否fd2变成可写的了
示意程序代码如下:

    fd1 = socket();//创建一个socket
    fd2 = socket();//创建一个socket
    while(1) {
        FD_ZERO (&readfds);
        FD_ZERO (&writefds);
        FD_SET (fd1, &readfds);
        FD_SET (fd2, &writefds);
        timeout.tv_sec=1;
        timeout.tv_uec=0;
        ret = select(fd1>fd2?(fd1+1):(fd2+1), &readfds, &writefds, NULL, &timeout);
        if(ret < 0) {printf("系统错误,select出错,错误代码:%d, 错误信息:%s", errno, strerror(errno));}
        else if(ret == 0) {printf("select超时返回,没有任何句柄状态发生变化!");}
        //有句柄状态发生了变化
        if(FD_ISSET(fd1, &readfds)) {
            fd1有数据可读;
            fd1里的数据被读出来;
        }
        if(FD_ISSET(fd2, &writefds)) {
            fd2可写;
            fd2里发送数据给对方;
        }
    }