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模型之选择模型(一)的更多相关文章

  1. 网络IO模型-异步选择模型(Delphi版)

    其实关于这个模型,网络上也有一个案例说明 老陈使用了微软公司的新式信箱.这种信箱非常先进,一旦信箱里有新的信件,盖茨就会给老陈打电话:喂,大爷,你有新的信件了!从此,老陈再也不必频繁上下楼检查信箱了, ...

  2. 一.Windows I/O模型之选择(select)模型

    1.选择(select)模型:选择模型:通过一个fd_set集合管理套接字,在满足套接字需求后,通知套接字.让套接字进行工作.避免套接字进入阻塞模式,进行无谓的等待.选择模型的核心的FD_SET集合和 ...

  3. windows socket网络编程--事件选择模型

    目录 事件选择模型概述 API详解 工作原理 代码实现 事件选择模型概述 Winsock提供了另一种有用的异步事件通知I/O模型--WSAEventSelect模型.这个模型与WSAAsyncSele ...

  4. ML 04、模型评估与模型选择

    机器学习算法 原理.实现与实践——模型评估与模型选择 1. 训练误差与测试误差 机器学习的目的是使学习到的模型不仅对已知数据而且对未知数据都能有很好的预测能力. 假设学习到的模型是$Y = \hat{ ...

  5. 机器学习如何选择模型 & 机器学习与数据挖掘区别 & 深度学习科普

    今天看到这篇文章里面提到如何选择模型,觉得非常好,单独写在这里. 更多的机器学习实战可以看这篇文章:http://www.cnblogs.com/charlesblc/p/6159187.html 另 ...

  6. windows下的IO模型之选择(select)模型

    1.选择(select)模型:选择模型:通过一个fd_set集合管理套接字,在满足套接字需求后,通知套接字.让套接字进行工作. 选择模型的核心是FD_SET集合和select函数.通过该函数,我们可以 ...

  7. ExtJS表格——行号、复选框、选择模型

    本篇的内容是为表格添加行号,和复选框,最后谈一下Ext的选择模型.内容比较简单,就直接上代码了.一. 设置行号   行号的设置主要问题在于删除某一行后需要重新计算行号  Ext.onReady(fun ...

  8. 莫烦python教程学习笔记——利用交叉验证计算模型得分、选择模型参数

    # View more python learning tutorial on my Youtube and Youku channel!!! # Youtube video tutorial: ht ...

  9. DDD:谈谈数据模型、领域模型、视图模型和命令模型

    背景 一个类型可以充当多个角色,这个角色可以是显式的(实现了某个接口或基类),也可以是隐式的(承担的具体职责和上下文决定),本文就讨论四个角色:数据模型.领域模型.视图模型和命令模型. 四个角色 数据 ...

随机推荐

  1. Java锁及AbstractQueuedSynchronizer源码分析

    一,Lock 二,关于锁的几个概念 三,ReentrantLock类图 四,几个重要的类 五,公平锁获取 5.1 lock 5.2 acquire 5.3 tryAcquire 5.3.1 hasQu ...

  2. Java并发编程原理与实战三:多线程与多进程的联系以及上下文切换所导致资源浪费问题

    一.进程 考虑一个场景:浏览器,网易云音乐以及notepad++ 三个软件只能顺序执行是怎样一种场景呢?另外,假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而 ...

  3. python 压缩每周生成的数据文件

    为了便于整理部分业务数据,以及存储管理, 写了此脚本.后期如果有需求,再改一下. #!/usr/bin/env python #coding:utf8 import os,sys,time,comma ...

  4. 自己写的一个小的剪刀——石头——布游戏的GUI程序

    很简单的一个程序,建议各位初学Java的同学可以试试写写这个程序: import javax.swing.JOptionPane; public class Game { public static ...

  5. iOS AES128 CBC No Padding加密解密

    最近的项目中数据传输用到加密,项目选择了AES128 CBC No Padding加密方式,PHP和Android方面的代码网上太多了.但是唯独没有iOS的,但是也有别的写法,但不是是AES128 C ...

  6. 【清华集训 2017】小Y的地铁 [模拟退火]

    小Y的地铁 Time Limit: 50 Sec  Memory Limit: 256 MB Description Input Output 对于每组输入数据,输出一行一个整数,表示除掉这 n 个换 ...

  7. package.json安装依赖的箭头?

  8. linux命令-grep+正则表达式用法

    目标文件/etc/passwd,使用grep命令或egrep 1.显示出所有含有root的行:egrep 'root' passwd 2.输出任何包含bash的所有行,还要输出紧接着这行的上下各两行的 ...

  9. GreenTrend

    ExpertforSQLServer(4.7.2)和ZhuanCloud(1.0.0)工具收集内容(在个人笔记本上测试) --SZC_Info.txt :: SQL专家云 v1. :: 开始收集 :: ...

  10. align-items和align-content的区别

    最近在研究flex布局,容器中有两个属性,是用来定义crossAxis测轴排列方式的.一开始接触align-items还可以理解感觉不难,后来看到align-content就感觉有点混淆了,特开一篇博 ...