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:谈谈数据模型、领域模型、视图模型和命令模型
背景 一个类型可以充当多个角色,这个角色可以是显式的(实现了某个接口或基类),也可以是隐式的(承担的具体职责和上下文决定),本文就讨论四个角色:数据模型.领域模型.视图模型和命令模型. 四个角色 数据 ...
随机推荐
- Java开发者应该列入年度计划的5件事
本文写了我今年计划要做的5件事.为了能跟踪计划执行的进度,就把这些事都列了出来.我觉得这些事对其它Java开发者而言也是不错的参考方向. 1.开发一个应用,通过Java来操作一种NoSQL数据库实现存 ...
- 希尔密码(Hill Cipher)的实现
原理应该不用多讲了,自己百度就可以. C++实现: #include <iostream> #include <string> #include <memory.h> ...
- Android 实现两个list分别出现(在某一时刻只出现一个控件)
第一种方法: 在.xml文件中将这两个List分别放入不同的布局管理器中,比如说 <RelativeLayout android:layout_width="match_parent& ...
- 退役 AFO
noi滚粗了 D类没学校要 回去高考 此博客停止更新 此文章可能会继续更新 看心情 [upd 2017.11.13] 看完今年noip log级别数据结构终于出现辣! 看来noip以后又多了一大块考点 ...
- hdu 1716 排列2(DFS搜索)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1716 排列2 Time Limit: 1000/1000 MS (Java/Others) Me ...
- Interval Minimum Number
Given an integer array (index from 0 to n-1, where n is the size of this array), and an query list. ...
- grpc 实现微服务生态笔记
微服务的发展可谓是一波三折,一代一代经历和N多技术成果,grpc只是其中一个,因为其东家是google,明显比较稳定.加上其强大的文档和技术支持和跨平台的支持,在企业级应用上有很大的可信任感,所以也有 ...
- mysql安装管理 -> 编译&yum_02
首先 mysql5.7是目前的主流稳定版本,下载地址可以参考官网下载 --- > 官网下载点我 笔记为markdown模式,博客园不太兼容,详细内容参考 --- 有道云笔记点我 mysq ...
- 04 Go 1.4 Release Notes
Go 1.4 Release Notes Introduction to Go 1.4 Changes to the language For-range loops Method calls on ...
- window.onload绑定多个事件 —— 两种解决方案
前言 有些函数,必须在网页加载完毕后执行.比如:涉及DOM操作的. 网页加载完毕时会触发一个onload事件,将函数绑定到这个事件上即可. window.onload = myFunction; 问题 ...