Winsock异步模式之一select 选择模式
2013-04-17 21:56
288 查看
Winsock异步模式之一select 选择模式
2010-02-25 16:25:43| 分类: 网络开发|字号 订阅最近在学习winsock的过程中遇到种种问题,最突出的就是资料比较少,而且不是很详细(特别是异步IO模型这一块),很多资料都是费了九牛二虎之力才在网上找到只言片语(哎,很多资料说的都不是特别清楚)。为了巩固我的学习成果,同时也是为了给后来者提供一点点的帮助,我决定把我的学习心得以及对winsock五种异步模式的理解记录下来。当然我对自己的要求是:不求面面俱到,但要让大部分人看懂。
如果你对winsock一点都不知道,那么请你先看看http://blog.csdn.net/Style_2009/archive/2009/12/02/4922602.aspx,并牢记那两个流程,至于为什么,我不说,你慢慢就会发现的。下面就开始吧。
Winsock异步模式之一select 选择模式----by Mr骢
select模型是最常见的I/O模型,其核心是一个名为select的函数,那么我们先来看看这个函数;
view plaincopy to clipboardprint?
int select(
int nfds,
fd_set FAR *readfds,
fd_set FAR *writefds,
fd_set FAR *exceptfds,
const struct timeval FAR *timeout
);
int select(
int nfds,
fd_set FAR *readfds,
fd_set FAR *writefds,
fd_set FAR *exceptfds,
const struct timeval FAR *timeout
);
利用这个函数,程序可以检查指定的套接字上是否有数据到来,或者能否向套接字写入数据。
参数解释:
参数1 nfds:这个参数是一个被忽略的参数,我们在程序中传入0即可,其目的是与伯克利套接字兼容。
参数2 readfds:可读性监视集合,可读性指有连接到来、有数据到来、连接已关闭、重置或终止。
参数3 writefds:可写性监视集合,可写性指数据可以发送、连接可以成功。
参数4 exceptfds:例外性监视集合,例外性指连接会失败、外带数据到来
参数4 timeout:该参数指定select会等待的时间,者结构很简单,要是有兴趣可以看看msdn
注意:select参数中的三个监视集合至少有一个不能为空,任何其它两个都可为空
下面在看看fd_set这个结构
view plaincopy to clipboardprint?
typedef struct fd_set {
u_int fd_count; // how many are SET?
SOCKET fd_array[FD_SETSIZE]; // an array of SOCKETs
} fd_set;
typedef struct fd_set {
u_int fd_count; // how many are SET?
SOCKET fd_array[FD_SETSIZE]; // an array of SOCKETs
} fd_set;
对这个结构我就不详细说明了,相信后面那两个英文注释大家都能看懂,我只说一点这个结构是用来装SOCKET的,把你要监视SOCKET传给这个结构,然后同select函数进行监视。Winsock提供4个宏来操作它,这四个宏是:
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函数,其思想就是让select函数对传入fd_set进行监视(fd_set中装有你的SOCKET句柄),如果没什么事发生select就将fd_set中的SOCKET清除。下面看个例子
view plaincopy to clipboardprint?
timeval outTime;
outTime.tv = 1; //设置等待时间为1s
outTime.usec = 0; //毫秒
fd_set fdread;
while(true)
{
FD_ZERO(&fdread);
FD_SET(sessionSock, &fdread)//sessionSock为之前创建的会话套接字
select(0, &fdread, NULL, NULL, &outTime);
if(FD_ISSET(sessionSock, &fdread))//判断套接字是否还在集合中
{
recv_cnt = recv(sessionSock, buf, bufSize, 0);
}
else
{
//没有数据写入,进行其他操作
}
}
timeval outTime;
outTime.tv = 1; //设置等待时间为1s
outTime.usec = 0; //毫秒
fd_set fdread;
while(true)
{
FD_ZERO(&fdread);
FD_SET(sessionSock, &fdread)//sessionSock为之前创建的会话套接字
select(0, &fdread, NULL, NULL, &outTime);
if(FD_ISSET(sessionSock, &fdread))//判断套接字是否还在集合中
{
recv_cnt = recv(sessionSock, buf, bufSize, 0);
}
else
{
//没有数据写入,进行其他操作
}
}
结束了吗,有问题吗?是否有人觉得奇怪,我这说的是异步I/O,但这个select依然会阻塞进程啊,不是设置了outTime的吗?此问题很好,select本身是会阻塞的,我们可以使用select实现阻塞式套接字(如上),也可以实现异步套接字。我个人对实现异步套接字的理解是:你可以单独使用一个线程来进行你select,也就是说select阻塞你单独的线程,说白了就是让线程来完成异步。
相关文章推荐
- Winsock异步模式之一select 选择模式
- [置顶] WinSock 异步I/O模型[2]---异步选择 - WSAAsyncSelect
- [置顶] WinSock 异步I/O模型[3]---事件选择 - WSAEventSelect
- [置顶] WinSock 异步I/O模型[1]---选择模型 - select
- WinSock 异步I/O模型[1]---选择模型 - select
- 异步选择WSAAsyncSelect
- 【网络编程】之八、异步选择WSAAsyncSelect
- Winsock异步事件通知模型WSAAsyncSelect
- Winsock的异步模式的I/O模型
- Winsock的事件I/O异步模型——WSAEventSelect
- Winsock的异步模式的I/O模型
- Windows操作系统I/O模型—笔记2(异步选择(WSAAsyncSelect)模型)
- Winsock异步模型之(事件通知模型 WSAAsyncSelect)
- 设计模式之How to Select a Design Pattern 如何选择设计模式
- Winsock异步模型之(事件通知模型 WSAAsyncSelect)
- 事件选择:Winsock提供了另一个有用的异步I/O模型
- Windows Socket I/O模型---Select模型、异步选择、事件选择
- 异步选择模式中使用完成端口做它的消息队列
- 【网络编程】之八、异步选择WSAAsyncSelect
- Winsock提供了一个很有用的异步I/O模型之WSAAsyncSelect