之所以称其为select模型是因为它主要是使用select函数来管理I/O的。这个模型的设计源于UNIX系统,目的是允许那些想要避免在套接字调用上阻塞的应用程序有能力管理多个套接字。

int select(

int nfds,                                                 // 忽略,仅是为了与Berkeley套接字兼容

fd_set* readfds,                                  // 指向一个套接字集合,用来检查其可读性

fd_set* writefds,                                 // 指向一个套接字集合,用来检查其可写性

fd_set* exceptfds,                              // 指向一个套接字集合,用来检查错误

const struct timeval* timeout           // 指定此函数等待的最长时间,如果为NULL,则最长时间为无限大

);

Select模型是最常见的I/O模型。

使用 int select( int nfds , fd_set FAR* readfds , fd_set FAR* writefds,fd_set FAR* exceptfds,const struct timeval FAR * timeout ) ;

函数来检查你要调用的Socket套接字是否已经有了需要处理的数据。

select包含三个Socket队列,分别代表: readfds ,检查可读性,writefds,检查可写性,exceptfds,例外数据。 timeout是select函数的返回时间。

例如,我们想要检查一个套接字是否有数据需要接收,我们可以把套接字句柄加入可读性检查队列中,然后调用select,如果,该套接字没有数据需要接收, select函数会把该套接字从可读性检查队列中删除掉,所以我们只要检查该套接字句柄是否还存在于可读性队列中,就可以知道到底有没有数据需要接收了。

timeout参数控制select完成的时间。若timeout参数为空指针,则select将一直阻塞到有一个描述字满足条件,否则的话,timeout指向一个timeval结构,其中指定了select调用在返回前等待多长时间。如果timeval为{0,0},则select立即返回,这可用于探询所选套接口的状态,如果处于这种状态,则select调用可认为是非阻塞的,且一切适用于非阻塞调用的假设都适用于它,举例来说,阻塞钩子函数不应被调用,且WINDOWS套接口实现不应yield。

函数调用成功,返回发生网络事件的所有套接字数量的总和。如果超过了时间限制返回0,失败则返回SOCKET_ERROR。

typedef struct fd_set {

u_int fd_count;                                       // 下面数组的大小

SOCKET fd_array[FD_SETSIZE];       // 套接字句柄数组

} fd_set;

  • FD_ZERO(*set)                            初始化set为空集合。集合在使用前应该总是清空
  • FD_CLR(s, *set)                          从set移除套接字s
  • FD_ISSET(s, *set)                       检查s是不是set的成员,如果是返回TRUE
  • FD_SET(s, *set)                           添加套接字到集合
 
    typedef struct timeval{
                  long tv_sec;                        // 指示等待多少秒
                  long tv_usec;                      // 指示等待多少毫秒
    } timeval;
 
下面给出使用select模式的例子,运行后在4567端口监听,接受客户端连接请求,打印出接收到的数据。(原来单线程也可以管理多个套接字)

//创建服务器套接字 
socket 
//绑定本地地址 
bind 
//进入监听模式 
listen 
//select模式 
//构造fd_set集合 
fd_set fdSocket;    
//清空fd_set集合并将服务器套接字加入 
FD_ZERO(&fdSocket);   
FD_SET(sListen, &fdSocket);   
//循环 
//复制一份fd_set集合并放入select中检测 
fd_set fdRead = fdSocket;   
int nRet = ::select(0, &fdRead, NULL, NULL, NULL);   
//根据select结果进行相应处理(accept read )

总结:通过select模式,实现了监听socket的accept和客户端的read之间,以及各个客户端之间的read,可以不用一直阻塞在那,而是在有相应事件的时候再进行阻塞处理,把accept和read两个长阻塞转化为select一个长阻塞。

     使用select的好处是程序能够在单个线程内同时处理多个套接字连接,这避免了阻塞模式下的线程膨胀问题。但是,添加到fd_set结构的套接字数量是有限制的,默认情况下,最大值是FD_SETSIZE,它在winsock2.h文件中定义为64。为了增加套接字数量,应用程序可以将FD_SETSIZE定义为更大的值(这个定义必须在包含winsock2.h之前出现)。不过,自定义的值也不能超过Winsock下层提供者的限制(通常是1024)。
    另外,FD_SETSIZE的值太大的话,服务器性能就会受到影响。例如有1000个套接字,那么在调用select之前就不得不设置这1000个套接字,select返回之后,又必须检查这1000个套接字。

Winsock IO模型之select模型的更多相关文章

  1. linux下多路复用模型之Select模型

    Linux关于并发网络分为Apache模型(Process per Connection (进程连接) ) 和TPC , 还有select模型,以及poll模型(一般是Epoll模型) Select模 ...

  2. Socket I/O模型之select模型

    socket网络编程中有多种常见的I/O模型: 1.blocking阻塞 2.nonblocking非阻塞 3.I/O multiplexing复用 4.signal driven 5.asynchr ...

  3. 【转】Select模型原理

    Select模型原理利用select函数,判断套接字上是否存在数据,或者能否向一个套接字写入数据.目的是防止应用程序在套接字处于锁定模式时,调用recv(或send)从没有数据的套接字上接收数据,被迫 ...

  4. Select模型原理

    Select模型原理 利用select函数,推断套接字上是否存在数据,或者是否能向一个套接字写入数据.目的是防止应用程序在套接字处于锁定模式时,调用recv(或send)从没有数据的套接字上接收数据, ...

  5. winsock编程select模型

    winsock编程select模型 网络服务端连接数量过多时,为每一个连接申请一个线程会让机器性能急剧下降(大多说是因为线程在用户态和内核态之间切换会占用大量的CPU时间片).为了解决多线程带来的性能 ...

  6. 很幽默的讲解六种Socket IO模型 Delphi版本(自己Select查看,WM_SOCKET消息通知,WSAEventSelect自动收取,Overlapped I/O 事件通知模型,Overlapped I/O 完成例程模型,IOCP模型机器人)

    很幽默的讲解六种Socket IO模型(转)本文简单介绍了当前Windows支持的各种Socket I/O模型,如果你发现其中存在什么错误请务必赐教. 一:select模型 二:WSAAsyncSel ...

  7. [编织消息框架][网络IO模型]NIO(select and poll)

    上面测试论证系统内核在read data时会阻塞,如果我们在把第一个阶段解决掉那么性能就会提高 NIO 编程 JDK 1.4中的java.nio.*包中引入新的Java I/O库,其目的是提高速度.实 ...

  8. I/O模型之二:Linux IO模式及 select、poll、epoll详解

    目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...

  9. windows socket编程select模型使用

    int select(         int nfds,            //忽略         fd_ser* readfds,    //指向一个套接字集合,用来检测其可读性       ...

随机推荐

  1. flex 组建重写

    flex历经几个版本的变化,其封装性也越来越规范. 今日flex的学习,总结是组件的重写. 项目中为使组件的针对性,易用性更强 ,免不了要重写组件. 要改变你的对手你的了解你的对手. 一个组件从被ne ...

  2. Mybatis配置中遇到的问题和问题分析

    1.为什么这么配置,这个配置主要是作用是什么,主要的是针对什么 mybatis之xml映射配置 sql语句当中 Example_Where_Clause 这个仅仅是一段sql语句吗? <trim ...

  3. leetcode:Palindrome Linked List

    Given a singly linked list, determine if it is a palindrome. Follow up:Could you do it in O(n) time ...

  4. 《OD学hadoop》第一周0626 作业二:Linux基础

    一.打包压缩 知识点: tar -zxvf -C PATH tar -jxvf tar -zcvf tar -jcvf tar:打包命令 -z 打包同时gzip压缩 -j 打包同时bzip2 -c 打 ...

  5. Android 第三方应用接入微信平台(1)

    关键字:微信开放平台   Android第三方应用接入微信 微信平台开放后倒是挺火的,许多第三方应用都想试下接入微信这个平台, 毕竟可以利用微信建立起来的关系链来拓展自己的应用还是挺不错的,可 以节约 ...

  6. HDU 1517 (类巴什博奕) A Multiplication Game

    如果n在[2, 9]区间,那么Stan胜. 如果n在[10, 18]区间,那么Ollie胜,因为不管第一次Stan乘上多少,第二次Ollie乘上一个9,必然会得到一个不小于18的数. 如果n在[19, ...

  7. hdu4638 group 树状数组

    连接:http://acm.hdu.edu.cn/showproblem.php?pid=4638 题意:就给给你n个数(大小在1-n里),然后给你连续的可以构成一个块,再给你N个询问,每个询问一个l ...

  8. windows下github pages + hexo next 搭建个人博客

    一.github pages 搭建个人博客一般需要购买域名和空间,github pages为我们提供了这两样东西,而且是免费的,相关介绍和使用方法参考这里 github pages. 二.Hexo 一 ...

  9. Java之网络编程笔记

    网络通讯要素: 1.IP地址 IP地址:用于标记一台计算机的身份证. IP地址由网络地址(确定网络)和主机地址(网络中的主机)组成. IP地址分为A类地址.B类地址.C类地址(常用).D类地址.E类地 ...

  10. 递归神经网络(Recurrent Neural Networks,RNN)

    在深度学习领域,传统的多层感知机(MLP)具有出色的表现,取得了许多成功,它曾在许多不同的任务上——包括手写数字识别和目标分类上创造了记录.甚至到了今天,MLP在解决分类任务上始终都比其他方法要略胜一 ...