• select()函数 的学习


    select()的介绍 全是拷贝的如下文章:

    https://www.cnblogs.com/wenqiang/p/5508541.html

    select()函数的用例代码摘录如下文章:

    https://blog.csdn.net/aiwoziji13/article/details/6688916

    1. select函数简介

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

    下面是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--->是一个时间结构体,用来设置超时时间。该参数是NULL,表示是阻塞操作

    select函数的返回值 :

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

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

    void FD_ZERO(fd_set *set);         //清空一个文件描述符的集合
    void FD_SET(int fd, fd_set *set);  //将一个文件描述符添加到一个指定的文件描述符集合中
    void FD_CLR(int fd, fd_set *set);  //将一个指定的文件描述符从集合中清除;
    int  FD_ISSET(int fd, fd_set *set);//检查集合中指定的文件描述符是否可以读写

    struct timeval 结构体可以精确到秒跟毫秒。用于设置阻塞时间;如果其成员设置为0,表示不阻塞,立即返回。

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

    下面是使用select()函数的一个例子:

    // test select()
    #include<stdio.h>
    #include<string.h>
    #include <fcntl.h>
    #include <assert.h> 
    
    #include <sys/select.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int main()
    {
        int fd = open("/dev/tty", O_RDONLY|O_NONBLOCK);
        assert(fd>0);
    
        int ret = 0;
        fd_set fd_set;
        struct timeval timeout;
    
        while(1) {
            FD_ZERO(&fd_set);
            FD_SET(fd, &fd_set);
    
            timeout.tv_sec = 5; //set timeout time
            timeout.tv_usec = 0;
    
            ret = select(fd+1, &fd_set, NULL, NULL, &timeout);
            if(-1 == ret) {
               printf("select failure
    ");
               return -1;
            } else if(0 == ret) {
               printf("time out 
    ");
            }
    
            if(FD_ISSET(fd, &fd_set)) {
                char ch;
                int num = read(fd, &ch, 1);
                //getchar();
                if('
    ' == ch) continue;
                else if ('q' == ch) break;
                else printf("ch = %c
    ", ch);
            }
        }
    
        close(fd);
        return 0;
    }
  • 相关阅读:
    css解决display:inline-block;产生的缝隙(间隙)
    js二进制与十进制互转
    js获取HTTP的请求头信息
    安装WampServer时出现的问题(丢失VCRUNTIME140.dll或MSVCR110.dll)以及解决办法
    学习安装并配置前端自动化工具Gulp
    解决overflow:hidden在安卓微信页面没有效果的办法
    Python 调用 ES、Solr、Phoenix
    Python 调用 Hprose接口、Dubbo接口、Java方法
    Python调用Redis
    robot用例执行常用命令(转)
  • 原文地址:https://www.cnblogs.com/jyfyonghu/p/10020876.html
Copyright © 2020-2023  润新知