C语言中select函数的使用

       一般用connect、accept、recv或recvfrom这类函数,程序阻塞,直至该套接字上接受到数据后程序才能继续运行。但是使用select函数可以实现非阻塞方式的程序。它能够监视我们需要监视的文件描述符的变化情况——读写或是异常。

Select的函数格式:

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

fd_set可以理解成存放一些fds的集合或者池子。

fd表示文件描述符。Linux系统中任何设备都是一个文件,表示该设备的指针就是文件描述符。

函数各个入参解释如下:

<1>maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,如果是在Linux环境上运行,该参数值不能错。如果在Windows中这个参数的值无所谓,可以设置不正确。

<2>readfds指针指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的读变化的。即我们关心是否可以从这些文件中读取数据了,当socket套接字接收到数据时,该fd即为可读状态。如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读,如果没有可读的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的读变化。 

<3>writesfds的含义和readfds相同,区别在于我们关心的是该文件是否可写而不是可读。当socket套接字准备发送数据时,该fd即为可写状态。

<4>errorfds,和上面两个相同,表示监听文件描述符的异常。

<5>timeout,是select的超时时间,这个参数至关重要,它可以使select处于三种状态,第一,若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;第三,timeout的值大于0,这就是等待的超时时间,即select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。 

 

函数返回值:

负值:select错误

正值:某些文件可读写或出错

0:等待超时,没有可读写或错误的文件。

当建立好socket套接字fd后,使用FD_SET函数将该fd放入select函数所监听的fd集合中。FD_ZERO用来初始化集合。

 

下面一段伪代码简单的介绍select函数在程序中的使用方法:

int main()

{

    fd_set socket_fds,int listen_fd,int result;

    listen_fd = socket();

    bind();listen();

    FD_ZERO(&socket_fds);

    FD_SET(listen_fd,&socket_fds);

    while(1)

    {

         result = select(FD_SETSIZE,socket_fds,NULL,NULL,0);//监听listen_fd是否可读,即是否接收到数据。

         if(result < 1)

         {

              reutrn 0;

         }

         for(fd = 0; fd < FD_SETSIZE; fd++)   

         {

               if(FD_ISSET(fd,&socket_fds))//监听的某个fd可读

               {

                     if(fd == listen_fd)//如果该fd是上面建立的套接字

                     {

                           recv();//接收数据

                           dosomething....

                     }

               }   

         }

    }

}

在更一般的使用场景中,当监听的文件描述符发生我们所期待的动作时,会调用回调函数进行数据接收和处理。有关回调函数的概念和使用方法,后面介绍~~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值