zoukankan      html  css  js  c++  java
  • 一.Windows I/O模型之选择(select)模型

    1.选择(select)模型:
    选择模型:通过一个fd_set集合管理套接字,在满足套接字需求后,通知套接字。让套接字进行工作。避免套接字进入阻塞模式,进行无谓的等待。选择模型的核心的FD_SET集合和select函数。通过该函数,我们可以们判断套接字上是否存在数据,或者能否向一个套接字写入数据。

    2.select函数:
    int select(
        int nfds,//忽略,只是为了兼容而存在。
        fd_set FAR* readfds,//可读性检查(有数据可读入,连接关闭,重设,终止)
        fd_set FAR* writefds,//可写性检查(有数据可发出)
        fd+set FAR* exceptfds,//带外数据检查(带外数据)
        const struct timeval FAR* timeout//超时
        );

    3.select模型的工作步骤:
    (1)首先把套接字加入到fd_set集合
    (2)检查套接字的可读写性
    (3)检查套接字是否还在fd_set集合上
    (4)处理数据

    4.在三个参数中(readfds、writefds和exceptfds),任何两个都可以是空值;但是,至少有一个不能为空值!最后一个参数timeout对应的是一个指针,它指向一个timeval结构,用于决select最多等待I/O操作完成多久的时间。如timeout是一个空指针,那么select函数会无限期地“等待下去,直到至少有一个套接字符合指定的条件后返回。select成功完成后,会在fd_set集合中,返回未完成的I/O操作的套接字句柄的总量。若超时,便会返回0。不管由于什么原因,假如select调用失败,都会返回SOCKET_ERROR错误。

    5.timeval结构体定义:
    struct timeval
    {
        long tv_sec;//秒数
        long tv_usec;//毫秒数
    };

    6.fd_set集合:用select函数对套接字进行监视之前,必须要将套接字分配给一个fd_set集合,设置好读、写以及带外数据的fd_set结构。将一个套接字分配给任何一个集合后,再来调用select进行监视,便可知道一个套接字上是否正在发生上述的I/O活动。Winsock提供了下列宏操
    作,对fd_set进行处理和检查:
        FD_ZERO(*set):初始化set
        FD_SET(s, *set):将套接字s加入集合set
        FD_CLR(s, *set):从set中删除套接字s。
        FD_ISSET(s,*set):检查s是否还在集合set上,在调用select函数之前必须对此进行判断。

    7.select模型的工作步骤:
    (1) 使用FD_ZERO宏,初始化自己感兴趣的每一个fd_set。
    (2) 使用FD_SET宏,将套接字句柄分配给自己感兴趣的每个fd_set。
    (3) 调用select函数,等待I/O操作的完成。
    (4) 根据select的返回值,我们便可判断出哪些套接字存在着尚未完成(待决)的I/O操作,.具体的方法是使用FD_ISSET宏,对每个fd_set集合进行检查。
    (5) 知道了每个集合中“待决”的I/O操作之后,对I/O进行处理,然后返回步骤1 ),继续进行select处理。
    (6)select返回后,它会修改每个fd_set结构,删除那些不存在待决I/O操作的套接字句柄。这正是我们在上述的步骤( 4 )中,为何要使用FD_ISSET宏来判断一个特定的套接字是否仍在集合中的原因。

    示例代码:

     1 SOCKET s;
     2 fd_set fdread;
     3 int ret;
     4 
     5 //初始化
     6 ...
     7 
     8 //Manage I/O on the socket
     9 while(1)
    10 {
    11     FD_ZERO(&fdread);//初始化集合
    12 
    13     FD_SET(s,&fdread);//添加套接字到集合上
    14 
    15     ret=select(0,&fdread,NULL,NULL,NULL);//调用select函数监视网络事件的完成情况
    16     if(ret==SOCKET_ERROR)
    17     {
    18         ...
    19     }
    20 
    21     if(res>0)
    22     {
    23         //处理数据
    24         ...
    25         
    26         if(FD_ISSET(s,&fdread))//检查套接字是否还在集合上
    27         {
    28             ...
    29         }
    30     }
    31     
    32 }
    View Code
  • 相关阅读:
    Jane Austen【简·奥斯汀】
    I Like for You to Be Still【我会一直喜欢你】
    Dialogue between Jack and Rose【jack 和 Rose的对话】
    git删除远程.idea目录
    码云初次导入项目(Idea)
    DelayQueue 订单限时支付实例
    eclipse安装spring的插件
    redis安装命令
    log4j详解
    jstree API
  • 原文地址:https://www.cnblogs.com/HPAHPA/p/7818720.html
Copyright © 2011-2022 走看看