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---协程理解
推文:python---基础知识回顾(七)迭代器和生成器 推文:Python协程深入理解(本文转载于该文章) 从语法上来看,协程和生成器类似,都是定义体中包含yield关键字的函数.yield在协程中 ...
- static的局限
static 的缺陷: 1.它只能调用static 变量. 2.它只能调用static方法. 3.不能引用this super 4.static变量在定义时必须初始化,且初始化的时间要早于非静态变量 ...
- 安装python包时遇到"error: Microsoft Visual C++ 9.0 is required"的简答
简答 在Windows下用pip安装Scrapy报如下错误, error: Microsoft Visual C++ 9.0 is required (Unable to find vcvarsall ...
- fvwm:还是觉得你最好
2008-07-12的老日志 用了gnome和xfce,还是有些厌了,摆弄了两天fvwm,发现虽然配置起来有点麻烦,但用起来还是它最贴心,而且占资源极少,系统使用过程中内存一直只用了五六十兆.我的鼠标 ...
- EF记录统一添加创建,修改时间
public class BaseEntity { public DateTime? DateCreated { get; set; } public string UserCreated { get ...
- Spring Boot 集成 MyBatis和 SQL Server实践
概 述 Spring Boot工程集成 MyBatis来实现 MySQL访问的示例我们见过很多,而最近用到了微软的 SQL Server数据库,于是本文则给出一个完整的 Spring Boot + M ...
- 【leetcode 简单】 第七十四题 缺失数字
给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数. 示例 1: 输入: [3,0,1] 输出: 2 示例 2: 输入: [9,6,4,2 ...
- SearchSploit
在我们的GitHub上的Exploit Database存储库中包含一个名为"searchsploit"的Exploit-DB的命令行搜索工具,该工具还允许您在任何地方随身携带一个 ...
- 【JSON】Ajax获得JSON字符串的处理方法
一. success : function(data){ var caseInfoView = eval('('+data.caseInfoView+')'); for(var key in case ...
- tomcat发布html静态页面
一.环境 在Linux系统安装JDK并配置环境变量,安装tomcat(在tomcat官网下载压缩包即可,我使用的是tomcat7 https://tomcat.apache.org/download- ...