Winsock—I/O模型之选择模型(一)
Winsock中提供了一些I/O模型帮助应用程序以异步方式在一个或多个套接字上管理I/O。
这样的I/O模型有六种:阻塞(blocking)模型,选择(select)模型,WSAAsyncSelect模型,WSAEventSelect模型,重叠(overlapped)模型,完成端口(completion port)模型。
选择模型:
目的:允许想要避免在套接字调用上阻塞的应用程序有能力管理多个套接字。
一、select函数
select函数可以确定一个或者多个套接字的状态。如果套接字上没有网络事件发生,便进入等待状态,以便执行同步I/O。
1 int select(int nfds, //仅是为了与套接字兼容,忽略
2 fd_set* readfds, //指向一个套接字集合,检查其可读性
3 fd_set* writefds, //检查一个套接字集合,检查其可写性
4 fd_set* exceptfds //指向一个套接字集合,检查错误
5 const struct timeval* timeout //指定函数最长等待时间,如果为NULL,则等待时间为无限长
6 );
函数调用成功,返回发生网络事件的所有的套接字数量的总和。如果超过了时间限制,返回0,失败则返回SOCKET_ERROR。
1、套接字集合
fd_set结构可以把多个套接字连接在一起,形成一个套接字集合。select函数可以测试这个集合中哪些套接字有事件发生。
WINSOCK2.h中的定义如下:
1 typedef struct fd_set{
2 u_int fd_count; //下面数组的大小
3 SOCKET fd_array[FD_SETSIZE]; //套接字句柄数组
4 }
WINSOCK中定义的4个操作fd_set套接字集合的宏:
1 FD_ZERO(*set); //初始化set为空集合。集合使用前应该总是清空。
2 FD_CLR(s,*set); //从set移除套接字s
3 FD_ISSET(s,*set) //检查s是不是set的成员,如果是返回TRUE.
4 FD_SET(s,*set) //添加套接字到集合
2、设置超时
最后的参数timeout是timeval结构的指针,它指定了select函数等待的最长的时间。如果设为NULL,select将会无限阻塞,直到有网络事件发生。
timeval结构定义如下:
1 typedef struct timeval
2 {
3 long tv_sec; //指示等待多少秒
4 long tv_usec; //指示等待多少毫秒
5 }timeval;
服务器端代码:
1 2
3 CInitSock theSock; //初始化Winsock库
4 int main()
5 {
6 USHORT nport = 4567; //此服务器监听的端口号
7 SOCKET sListen = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
8 sockaddr_in sin;
9 sin.sin_family = AF_INET;
10 sin.sin_port = htons(nPort);
11 sin.sin_addr.S_un.S_addr = INADDR_ANY; //绑定监听套接字到本地
12 if(bind(sListen,(sockaddr*)&sin,sizeof(sin)==SOCKET_ERROR) //绑定套接字失败
13 {
14 printf("Failed bind()n\");
15 return -1;
16 }
17 listen(sListen,5); //进入监听模式
18 fd_set fdSocket; //创建套接字集合
19 FD_ZERO(&fdSocket); //初始化套接字结合
20 FD_SET(&sListen,&fdSocket); //将监听套接字添加进套接字集合中
21 while(TRUE)
22 {
23 fd_set fdRead = fdSocket; //将fdSocket集合拷贝到fdRead
24 int nRet = select(0,&fdRead,NULL,NULL,NULL); //当有事件发生发生时,select函数将移除fdRead集合中没有未决I/O操作的套接字句柄,然后返回。
25 if(nRet>0)
26 {
27 //通过将原来的fdSocket集合与select处理过的fdRead集合比较,确定有哪些套接字有未决I/O,进一步处理这些I/O。
28 for(int i=0;i<(int)fdSocket.fd_count;i++)
29 {
30 if(FD_ISSET(fdSocket.fd_array[i],&fdRead))
31 {
32 if(fdSocket.fd_count<FD_SETSIZE)
33 {
34 sockaddr_in addrRemote;
35 int nAddrLen = sizeof(addrRemote);
36 SOCKET sNew = accept(sListen,(SOCKADDR*)&addrRemote,&nAddrlen);
37 FD_SET(sNew,&fdSocket);
38 printf("接收到连接(%s)\n",inet_ntoa(addrRemote.sin_addr));
39 }
40 else
41 {
42 printf("Too Much Connections!");
43 continue;
44 }
45 }
46 else
47 {
48 char szText[256];
49 int nRecv = recv(fdSocket.fd_array[i],szText,strlen(szText),0); //接收
50 if(nRecv>0)
51 {
52 szText[nRecv] = '\0';
53 printf("接收到数据:%s\n",szText);
54 }
55 else
56 {
57 closesocket(fdRead.fd_array[i]);
58 FD_CLR(fdSocket.fd_array[i],&fdSocket);
59 }
60 }
61 }
62 }
63 }
64 else
65 {
66 printf("Failed select()\n");
67 break;
68 }
69 }
70 return 0;
71 }
Winsock—I/O模型之选择模型(一)的更多相关文章
- 网络IO模型-异步选择模型(Delphi版)
其实关于这个模型,网络上也有一个案例说明 老陈使用了微软公司的新式信箱.这种信箱非常先进,一旦信箱里有新的信件,盖茨就会给老陈打电话:喂,大爷,你有新的信件了!从此,老陈再也不必频繁上下楼检查信箱了, ...
- 一.Windows I/O模型之选择(select)模型
1.选择(select)模型:选择模型:通过一个fd_set集合管理套接字,在满足套接字需求后,通知套接字.让套接字进行工作.避免套接字进入阻塞模式,进行无谓的等待.选择模型的核心的FD_SET集合和 ...
- windows socket网络编程--事件选择模型
目录 事件选择模型概述 API详解 工作原理 代码实现 事件选择模型概述 Winsock提供了另一种有用的异步事件通知I/O模型--WSAEventSelect模型.这个模型与WSAAsyncSele ...
- ML 04、模型评估与模型选择
机器学习算法 原理.实现与实践——模型评估与模型选择 1. 训练误差与测试误差 机器学习的目的是使学习到的模型不仅对已知数据而且对未知数据都能有很好的预测能力. 假设学习到的模型是$Y = \hat{ ...
- 机器学习如何选择模型 & 机器学习与数据挖掘区别 & 深度学习科普
今天看到这篇文章里面提到如何选择模型,觉得非常好,单独写在这里. 更多的机器学习实战可以看这篇文章:http://www.cnblogs.com/charlesblc/p/6159187.html 另 ...
- windows下的IO模型之选择(select)模型
1.选择(select)模型:选择模型:通过一个fd_set集合管理套接字,在满足套接字需求后,通知套接字.让套接字进行工作. 选择模型的核心是FD_SET集合和select函数.通过该函数,我们可以 ...
- ExtJS表格——行号、复选框、选择模型
本篇的内容是为表格添加行号,和复选框,最后谈一下Ext的选择模型.内容比较简单,就直接上代码了.一. 设置行号 行号的设置主要问题在于删除某一行后需要重新计算行号 Ext.onReady(fun ...
- 莫烦python教程学习笔记——利用交叉验证计算模型得分、选择模型参数
# View more python learning tutorial on my Youtube and Youku channel!!! # Youtube video tutorial: ht ...
- DDD:谈谈数据模型、领域模型、视图模型和命令模型
背景 一个类型可以充当多个角色,这个角色可以是显式的(实现了某个接口或基类),也可以是隐式的(承担的具体职责和上下文决定),本文就讨论四个角色:数据模型.领域模型.视图模型和命令模型. 四个角色 数据 ...
随机推荐
- python---函数补充(变量传递),语句执行顺序(入栈顺序)
一:函数补充 默认作为函数参数的数据,是浅拷贝传递.不是和C等语言一样,产生一个临时变量. class T: def __init__(self,num): print(id(num)) self.n ...
- ElastAlert监控日志告警Web攻击行为
由于公司需要监控web攻击行为,而因某些原因搭不了waf,才不得不用ElastAlert进行告警,此为前提. 一.ELK安装 Elasticsearch 是一个分布式.可扩展.实时的搜索与数据分析引擎 ...
- [Apio2012]dispatching 主席树做法
bzoj 2809: [Apio2012]dispatching http://www.lydsy.com/JudgeOnline/problem.php?id=2809 Description 在一 ...
- jQuery.Validator Sample
<!DOCTYPE html> <html> <head> <title></title> <script src="./j ...
- IT人应当知道的10个行业小内幕
如果你打算从事IT行业或刚进入这个行业,也许本文下面的小内幕会吓到你,因为这些事平常都不会公开讨论的.如果你是IT资深人士,或许你已经遇到其中的大部分了.如果你愿意,请一起来参与讨论吧. 这些内幕大多 ...
- iOS6下实现滑动返回
[转载请注明出处] 之前在看iOS7滑动返回时,发现了一个iOS6 SDK下的第三方实现,今天偶然间发现了作者在其博客上对该实现的一些心得,读来深觉之前的思考太过肤浅,许多实际的问题没有考虑到.帖子链 ...
- JavaScript的基本介绍
JavaScript入门介绍 输出语句:document.write() 1.执行顺序:从上到下,每一天语句是要加分号的,如果不加的话,浏览器会默认帮你自动添加,分号. 2.注释:一行注释就是 ...
- [转]边框回归(Bounding Box Regression)详解
https://blog.csdn.net/zijin0802034/article/details/77685438 Bounding-Box regression 最近一直看检测有关的Paper, ...
- Jetson TX1 安装Kinect驱动
1.添加Universe源 $ sudo apt-add-repository universe $ sudo apt-get update 2.安装编译工具和依赖项 $ sudo apt-get i ...
- MFC将二进制文件导入资源后释放
1.前言 前一篇笔记记录了怎么修改PE,此篇记录下如何利用自身的资源文件. 2.编程思路 获得资源句柄 - 获得资源文件大小 - 加载资源文件 - 锁定资源并获得其指针. 3.实践代码 1)编译以下代 ...