select函数介绍及使用

select函数介绍及使用

1.select函数

  • 函数原型
int select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, 			   struct timeval* timeout);
  • 参数:

    • nfds:所有文件描述符中最大的文件描述符+1

    • readfds:传入传出参数(位图),读 文件描述符监听集合

    • writefds:传入传出参数(位图),写 文件描述符监听集合,常为NULL

    • exceptfds:传入传出参数(位图),异常 文件描述符监听集合,常为NULL

      操作位图的参数:

      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);			//将集合整体清空
      
    • timeout:时间限制,NULL表示阻塞,0则不阻塞(轮询)

  • 返回值:

    成功:大于0表示所有监听集合中满足对应事件的总数

    ​ 等于0表示没有满足监听条件的文件描述符

    失败:-1,设置errno

2. select多路IO转接

  • 原理:借助内核,用select来监听客户端连接和数据通信

  • 应用的大致框架

    lfd = socket();       //创建套接字
    bind();               //绑定地址结构
    listen();             //设置监听上限
    fd_set rset, allset;  //创建读事件文件描述符集合rest,allset为暂存集合
    int maxfd;            //记录最大的文件描述符 
    FD_ZERO(&allset);     //将读监听集合清空
    FD_SET(lfd, &allset); //将lfd添加到读监听集合中
    while(1)
    {
        rset = allset;       //保存监听集合 
        //监听文件描述符集合对应事件
    	ret = select(maxfd + 1, &rset, NULL, NULL, NULL);  
     	if(FD_ISSET(lfd, &rset))  //判断是否有连接事件发生
     	{
    	    cfd = accept();       //建立连接
     	    FD_SET(cfd, &allset); //加入到监听描述符集合中去
            if(maxfd < cfd)
            {
                maxfd = cfd       //保持maxfd为最大的文件描述符
            }
            if(0 = --ret)         //如果只有连接事件后续代码不再运行
                continue;
     	}
        //处理数据收发事件
        for(i = lfd + 1; i <= maxfd; i++)
        {
            if(FD_ISSET(i, &rset))      //判断是否有对应的事件发生
            {
                if(Read(i) == 0)        //套接字已经关闭
                {
                    close(i);
                    FD_CLR(i, &allset); //接触select的监控
                }
                else if(Read(i) > 0)
                {
                    //对数据进行处理
                }
            }
        }
    }
    

3.select的优缺点

  • 缺点:

    • 监听上限收到文件描述符限制,最大为1024。
    • 需要自己检测满足条件的fd,编码难度较大。
  • 优点:

    • 跨平台。

你可能感兴趣的:(Linux网络编程)