zoukankan      html  css  js  c++  java
  • 网络编程之select

    一 select函数简介

      select一般用在socket网络编程中,在网络编程的过程中,经常会遇到许多阻塞的函数,网络编程时使用的recv, recvfrom、connect函数都是阻塞的函数,当函数不能成功执行的时候,程序就会一直阻塞在这里,无法执行下面的代码。这是就需要用到非阻塞的编程方式,使用 selcet函数就可以实现非阻塞编程。
    selcet函数是一个轮循函数,即当循环询问文件节点,可设置超时时间,超时时间到了就跳过代码继续往下执行

      select(),确定一个或多个套接口的状态,本函数用于确定一个或多个套接口的状态,对每一个套接口,调用者可查询它的可读性、可写性及错误状态信息,用fd_set结构来表示一组等待检查的套接口,在调用返回时,这个结构存有满足一定条件的套接口组的子集,并且select()返回满足条件的套接口的数目。

      通常采用select实现多路复用,也就是说可以同时监听多个文件描述符;

    下面是select的函数原型:

     /* According to POSIX.1-2001 */
    #include <sys/select.h>
      
    int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);

    下面进行具体的解释:

    第一个参数:int nfds--->是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1

    第二个参数:fd_set *readfds---->用来检查一组可读性的文件描述符。

    第三个参数:fd_set *writefds---->用来检查一组可写性的文件描述符。

    第四个参数:fd_set *exceptfds---->用来检查文件文件描述符是否异常

    第五个参数:sreuct timeval *timeout--->是一个时间结构体,用来设置超时时间

    timeout:最多等待时间,对阻塞操作则为NULL

    select函数的返回值 
    负值:select错误
    正值:表示某些文件可读或可写
    0:等待超时,没有可读写或错误的文件

    下面是一些跟select一起使用的函数及结构的作用

    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);//检查集合中指定的文件描述符是否可以读写

    struct timeval结构是用来设置超时时间的,该结构体可以精确到秒跟毫秒

    struct timeval {
           time_t         tv_sec;     /* seconds */
           suseconds_t    tv_usec;    /* microseconds */
    };

    下面是select常用的一个例子:

    #include <stdio.h>#include <stdio.h 
    #include <stdlib.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int main(int argc, cahr **argv)
     {
        struct timeval timeout;
        int ret = 0;
        fd_set rfds;
     
        FD_ZERO(&rfds);//清空描述符集合 
        FD_SET(0, &rfds);//将标准输入(stdin)添加到集合中
        FD_SET(sockfd, &rfds);//将我们的套接字描述符添加到集合中
        /*设置超时时间*/
        timeout.tv_sec = 1;   
        timeout.tv_usec = 0;
    
        /*监听套接字是否为可读*/
        ret = select(sockfd+1, &rfds, NULL, NULL, &timeout);
        if(ret == -1) {//select 连接失败
            perror("select failure
    ");
            return 1;
        }   
        else if(ret == 0) {//超时(timeout)
            return 1;
        }   
    
        if(FD_ISSET(pesockfd, &rfds)) {//如果可读
                        
                //recv or recvfrom
                ..................
        }
       return 0; 
      }

    转自:

    网络编程之select

    宝剑锋从磨砺出 梅花香自苦寒来
  • 相关阅读:
    数据库表结构变动发邮件脚本
    .net程序打包部署
    无法登陆GitHub解决方法
    netbeans 打包生成 jar
    第一次值班
    RHEL6 纯命令行文本界面下安装桌面
    C语言中格式化输出,四舍五入类型问题
    I'm up to my ears
    How to boot ubuntu in text mode instead of graphical(X) mode
    the IP routing table under linux@school
  • 原文地址:https://www.cnblogs.com/GHzcx/p/9363443.html
Copyright © 2011-2022 走看看