socket select()模型
转载:http://www.cnblogs.com/xiangshancuizhu/archive/2012/10/05/2711882.html
由于socket recv()方法是阻塞式的,当有多个客户端连接服务器时,其中一个socket的recv调用产生了阻塞,使其他链接不能继续。如果想改变这种一直等下去的焦急状态,可以多线程来实现(不再等待,同时去recv,同时阻塞),每个socket连接使用一个线程,这样效率十分低下,根本不可能应对负荷较大的情况(是啊,占用各种资源,电脑啊,你耗不起)。
这时候我们就可以采用select模型,select允许进程指示内核等待多个事件中的任何一个发生,并仅在有一个或多个事件发生或经历一段指定的时间后才唤醒它。select告诉内核对哪些描述字感兴趣以及等待多长时间。这就是所谓的非阻塞模型,就是进程或线程执行此函数时不必非要等待事件发生,一旦执行肯定返回,以及返回值得不同来反应函数的执行情况,如果事件发生则与阻塞方式相同,若事件没有发生则返回一个代码来告知事件未发生,而进程或线程继续执行,所以效率较高。
select的函数原型:
int select ( int nfds, //Winsock中此参数无意义 fd_set* readfds, //进行可读检测的Socket fd_set* writefds, //进行可写检测的Socket fd_set* exceptfds, //进行异常检测的Socket const struct timeval* timeout //非阻塞模式中设置最大等待时间 ) |
参数列表:
int maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!在Windows中这个参数的值无所谓,可以设置不正确。
fd_set *readfds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的读变化的,即我们关心是否可以从这些文件中读取数据了,如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读,如果没有可读的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的读变化。
fd_set *writefds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的写变化的,即我们关心是否可以向这些文件中写入数据了,如果这个集合中有一个文件可写,select就会返回一个大于0的值,表示有文件可写,如果没有可写的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的写变化。
fd_set *errorfds同上面两个参数的意图,用来监视文件错误异常。
struct timeval* timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态:
第一,若将NULL以形参传入,即不传入时间结构,就是将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;
第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;
第三,timeout的值大于0,这就是等待的超时时间,即 select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。
返回值:负值:select错误
正值:某些文件可读写或出错
0:等待超时,没有可读写或错误的文件
参数解释:
参数1 nfds:这个参数是一个被忽略的参数,我们在程序中传入0即可,其目的是与伯克利套接字兼容。
参数2 readfds:可读性监视集合,可读性指有连接到来、有数据到来、连接已关闭、重置或终止。
参数3 writefds:可写性监视集合,可写性指数据可以发送、连接可以成功。
参数4 exceptfds:例外性监视集合,例外性指连接会失败、外带数据到来
参数4 timeout:该参数指定select会等待的时间,者结构很简单,要是有兴趣可以看看msdn
注意:select参数中的三个监视集合至少有一个不能为空,任何其它两个都可为空
fd_set的结构,这个结构是用来装SOCKET的,把要监视SOCKET传给这个结构,然后同select函数进行监视。
struct fd_set { u_int fd_count; // how many are SET? SOCKET fd_array[FD_SETSIZE]; // an array of SOCKETs } ; |
select模型紧密结合的四个宏:
FD_CLR( s,*set) 从队列set删除句柄s。
FD_ISSET( s, *set) 检查句柄s是否存在与队列set中。
FD_SET( s,*set )把句柄s添加到队列set中。
FD_ZERO( *set ) 把set队列初始化成空队列。
select选择模式倚赖于select函数,其思想就是让select函数对传入fd_set进行监视(fd_set中装有你的SOCKET句柄),如果没什么事发生select就将fd_set中的SOCKET清除。
如:
timeval outTime; outTime.tv = 1; //设置等待时间为1s outTime.usec = 0; //毫秒 fd_set fdread; while ( true ) { FD_ZERO(&fdread); FD_SET(sessionSock, &fdread) //sessionSock为之前创建的会话套接字 if( select(0, &fdread, NULL, NULL, &outTime) > 0) {
if (FD_ISSET(sessionSock, &fdread)) //判断套接字是否还在集合中 { recv_cnt = recv(sessionSock, buf, bufSize, 0); } else { //没有数据写入,进行其他操作 } }
} |
socket select()模型的更多相关文章
- socket select模型
由于socket recv()方法是堵塞式的,当多个客户端连接服务器时,其中一个socket的recv调用时,会产生堵塞,使其他连接不能继续. 如果想改变这种一直等下去的焦急状态,可以多线程来实现(不 ...
- C# Socket select模型
http://www.cnblogs.com/Clingingboy/archive/2011/07/04/2097806.html http://www.cnblogs.com/RascallySn ...
- u3d局域网游戏网络(c# socket select 模型)——续
原文:http://www.cnblogs.com/saucerman/p/5555793.html 因为项目要加语音.语音数据都非常大.所以顺带就把之前写的网络模块一起测试了. 然后发现了一些bug ...
- u3d局域网游戏网络(c# socket select 模型)
之前写了一篇. 发完之后第二天实际应用到游戏之后还是发现了一些小毛病. 比如网络模块有重复使用(多对象)的情况.所以将静态类该成了普通类. 比如安卓下会有些异常出现导致游戏逻辑不正常.所以网络相关的函 ...
- c# socket select 模型代码(u3d)
其实写过多次网络链接.但是因为换了工作,又没电脑在身边,所以以前的代码都没办法翻出来用. 所以从今天起,一些常用的代码只好放到网上. 公司有一个局域网的游戏.本来想用u3d的rpc就可以完成.但是后来 ...
- windows socket编程select模型使用
int select( int nfds, //忽略 fd_ser* readfds, //指向一个套接字集合,用来检测其可读性 ...
- socket编程的select模型
在掌握了socket相关的一些函数后,套接字编程还是比较简单的,日常工作中碰到很多的问题就是客户端/服务器模型中,如何让服务端在同一时间高效的处理多个客户端的连接,我们的处理办法可能会是在服务端不停的 ...
- socket之 select模型
前段时间一直想学习网络编程的select模型,看了<windows网络编程>的介绍,参考了别人的博客. 这里的资料主要来自http://www.cnblogs.com/RascallySn ...
- 很幽默的讲解六种Socket IO模型 Delphi版本(自己Select查看,WM_SOCKET消息通知,WSAEventSelect自动收取,Overlapped I/O 事件通知模型,Overlapped I/O 完成例程模型,IOCP模型机器人)
很幽默的讲解六种Socket IO模型(转)本文简单介绍了当前Windows支持的各种Socket I/O模型,如果你发现其中存在什么错误请务必赐教. 一:select模型 二:WSAAsyncSel ...
随机推荐
- 开启apache服务
安装后如果需要手动添加Sevice,可以按照如下方法: Apache版本:httpd-2.2.15_win32 Apache Service Monitor 提示:“No services insta ...
- API变了,客户端怎么办?
使用ASP.NET Web Api构建基于REST风格的服务实战系列教程[九]——API变了,客户端怎么办? 系列导航地址http://www.cnblogs.com/fzrain/p/3490137 ...
- Excel开发
浅谈Excel开发:九 Excel 开发中遇到的常见问题及解决方法 Excel开发过程中有时候会遇到各种奇怪的问题,下面就列出一些本人在开发中遇到的一些比较典型的问题,并给出了解决方法,希望对大家 ...
- 【ios开发】iOS App测试方案
之前IOS测试一半都是采用的Testflight,但是2014.2.19日以后,testflight已经不提供新注册的用户下载SDK了. 但是不用担心我们还可以采用其他几种方案. 1)Ubertest ...
- 用NPOI实现导入导出csv、xls、xlsx数据功能
用NPOI实现导入导出csv.xls.xlsx数据功能 直接上代码 首先定义一个接口 如果需要直接操作文件的话,就自己在封装一次 然后定义csv类的具体实现 这个需要引入命名空间LumenWo ...
- Hive中抽取连续多天登录用户
昨天群上有人发个阿里的面试题,题目描述大概如下: 数据源:用户登录表,只有俩个字段,uid和dt 试用HQL抽取出连续登录了K天的用户uid 第一个想法就是直接用一个UDF解决,按uid分组,把dt收 ...
- 牛顿法(Newton's Method)
Newton's Method 在求最优解时,前面很多地方都用梯度下降(Gradient Descent)的方法,但由于最优步长很难确定,可能会出现总是在最优解附近徘徊的情况,致使最优解的搜索过程很缓 ...
- ckedit 在源码模式下插入文本
ckedit的源码模式下是禁用insertText方法的 ,下面是解决方案 if(CKEDITOR.instances[Itemname].mode=='wysiwyg'){ CKEDITOR.ins ...
- SQL Server监控清单
SQL Server监控清单 一. 服务器1. 状态监控(1) 服务器是否可访问?(2) 相应的数据库服务是否启用?(3) 操作系统事件日志中的错误或告警(4) 磁盘可用空间 服务器状态监控,不管使用 ...
- HTTP协议 HttpWebRequest和 Socket的一点总结
HTTP协议 HttpWebRequest和 Socket的一点总结 相信接触过网络开发的人对HTTP.HttpWebRequest.Socket这些东西都不陌生吧.它们之间的一些介绍和关系我这里都忽 ...