非阻塞IO--Select

select函数实现阻塞和非阻塞IO:

简介:select函数可是实现,对文件操作的阻塞与非阻塞。

改变参数struct timeval *timeout可以实现阻塞与非阻塞控制

相关结构体:

struct fd_set:存放文件描述符的集合(文件句柄);

struct fd_set的操作方法:

FD_ZERO(fd_set *) :清空文件描述符集合

FD_CLR(int ,fd_set*) :从文件描述符集合中删除某个文件描述符

FD_SET(int ,fd_set* ) :向文件描述符集合中添加一个文件描述符

FD_ISSET(int ,fd_set* ):检测当前文件描述符是否可以操作

时间结构体:struct timeval{

__time_t tv_sec;         /* Seconds.  秒*/ 
__suseconds_t tv_usec;   /* Microseconds.微妙 */

}

函数原型:

int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);

参数1 int maxfdp: 传入文件描述符集合中的数值最大的文件描述符的数值+1;

参数2 fd_set *readfds:要监控的文件描述符集合,这里监控文件描述符集合中文件描述符的读状态变化, 即:文件表述是否有数据可以读取

参数3 fd_set *writefds 要监控的文件描述符集合,这里监控文件描述符集合中文件描述符的写状态变化 即:文件描述符是否可以写数据

参数4 fd_set *errorfds 要监控的文件描述符集合,这里监控文件描述符集合中的文件描述是否有异常。

参数5 struct timeval *timeout select的超时时间设定,它可以设定select的三种执行状态;

a.入参为 NULL: select进入阻塞状态,即:程序会阻塞在这里,直到文件描述符集合中 的文件描述符状态发生变化,程序才会继续运行。

b.入参设定时间为零( struct timeval timeout={0,0} 这时select会进入完全非阻塞状 态,无论文件描述符集合中的文件描述符是否变化,都会立即执行然后 返回。

c.入参设定时间大大于0(struct timeval timeout={>0,>0})这时select会进入半阻塞状态,以 参数设定的时间为一个周期,如果一个周期内文件描述符集合中的文件 描述符状态有变化,立即返回;如果一个周期内文件描述符集合中的文 件描述符没有变化,到周期结束时,即返回。

返回值:

负值:select执行出错;

0  :监控的文件描述符集合中的文件描述符,没有状态变化,即:没有文件描述符有数据可以读     取,没有文件描述符有写的变化,没有文件描述符出现操作异常;

正值:有文件描述符的状态发生变化,这时就应该使用FD_ISSET判断是哪一个文件描述符的状态发 生了变化然后进行相应的操作。

例子:

main()

{

    int sock;

    FILE *fp;

    struct fd_set fds;

    struct timeval timeout={3,0}; //select等待3秒,3秒轮询,要非阻塞就置0

    char buffer[256]={0}; //256字节的接收缓冲区

 

    while(1)

    {

        FD_ZERO(&fds); //每次循环都要清空集合,否则不能检测描述符变化

        FD_SET(sock,&fds); //添加描述符

        FD_SET(fp,&fds); //同上

        maxfdp=sock>fp?sock+1:fp+1; //描述符最大值加1

        switch(select(maxfdp,&fds,&fds,NULL,&timeout)) //select使用

        {

            case -1: exit(-1);break; //select错误,退出程序

            case 0:break; //再次轮询

            default:

            if(FD_ISSET(sock,&fds)) //测试sock是否可读,即是否网络上有数据

            {

                recvfrom(sock,buffer,256,.....);//接受网络数据

                if(FD_ISSET(fp,&fds)) //测试文件是否可写

                fwrite(fp,buffer...);//写入文件

                buffer清空;

             }// end if break;

        }// end switch

    }//end while

}//end main


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值