1 select实现IO复用的思路02
下面的都是伪代码,主要讲究思路。
- 1)lfd=socket()。
- 2)bind()。
- 3)listen()。
- 4)将lfd添加到select的读集合用于传入,借助内核帮我们监听事件,而不直接调用accept函数监听。为了方便我们只需要添加读集合即可。
fd_Set rset,allset;//rset为读监听的集合
FD_ZERO(&rset);
FD_SET(lfd,&rset);
int ret = select(lfd+1, &rset, NULL, NULL, NULL);//注意,当select执行完毕rset变成传出参数了
- 6)然后将内核监听到的请求即请求连接(lfd触发),请求通信(cfd触发)进行处理。即利用select传出的参数rset文件描述符集合进行处理,因为rset里面是满足lfd,cfd的请求。如果有新客户端请求连接,那么lfd将在rset中,若客户端请求通信,那么cfd将在rset中,否则不在。这里需要注意,ret返回的总事件数只是能让你快速判断是否有请求事件发生,或者判断错误,实际作用一般就是这两个。
select的所有的操作都是基于rset文件描述符集合来处理。
//1 select的返回值一般用于判断错误
if (ret < 0)
perr_exit("select error");
//2 判断客户端是否有新的请求建立连接
if (FD_ISSET(listenfd, &rset)) {
/* new client connection */
connfd = accept();
//其它处理...
}
//3 遍历所有文件描述符,依次查看描述符是否在rset出现,若出现,说明客户端有对应请求。
//即处理cfd通信描述符
for(i = lfd + 1; i<=最大文件描述符数;i++){
if(FD_ISSET(i, &rset)){
//读写操作
}
}
以上就是select实现IO复用的思路,select不建议深入。