首页 > 代码库 > I/O模型之Select模型
I/O模型之Select模型
刚刚又看了一下I/O模型的相关知识做了一下总结,与大家一同交流.
Selct 模型说的就是在套接字集合fd_set中的操作(可将多个套接字连在一起,形成套接字集合)
套接字集合呢,又分为了3中形态,对应表示的关系如下:
套接字集合 有事件发生 到底啥事呢
readfds select函数等待 有未决连接请求 或 数据可读 或 连接关闭/重启/中断
writefds select函数等待连接成功(调用connect) 或 数据可写
exceptfds select函数等待连接失败 或 OOB数据可读
而我们判断是否可读可写等操作主要使用下面的方法,举个例子:
测试某套接字S是否可读,将它添加到readfds中,等待select函数返回,调用完成后判读S是否还在readfds里面即可
大致流程就是这样的:
(1)初始化一个套接字集合fdsocket,添加监听套接字句柄sListen到这个集合:
fd_set fdsocket;
FD_SET(sListen,&fdSocket);
(2)当fdsockt集合的一个拷贝fdRead传递给select函数,当有事件发生时,select函数就会移除fdRead中没有的未决的套接字句柄,并返回:
fd_set fdRead=fdSocket;
int nRet=::select(0,&fdRead,null,null,null);
(3)通过将原来的fdSocket集合与select处理过的fdRead比较,确定有哪些套接字有未决I/O,并进一步处理他们:
for(int i=0;i<(int)fdSocket.fd_count;i++)
{
if(FD_ISSET(fdSocket.fd_array[i],&fdRead))//判断是否存在可读
{
if(fdSockt.fd_array[i] == sListen)//代表监听套接字想连呐
{
sockaddr_in addrRemote;
int nAddrLen =sizeof(addrRemote);
SOCKET sNew=::accept(sListen,(SOCKADDR*)&addrRemote,&nAddrLen);
FD_SET(sNew,&fdSockt);
}
else//说明有数据可读了
{
char szText[256];
int nRecv=::recv(fdSocket.fd_array[i],szText,strlen(szText),0);
}
}
}
可以知能否写,跟这个差不多。
选择模型的好处是能够在单个线程内处理多个套接字请求,但添加到fd_set结构的套接字数量是有限的默认为64个,最多也只能到1024个。
如果套接字过多,在调用select之前就不得不设置这1000个套接字,select返回之后,右必须检查这1000个套接字。
最后是我喜欢的一句话:
某些坚持成就了一系列的偶然。
I/O模型之Select模型