select模型各个操作的总结

在《unix网络编程》中,介绍了select模型可用于将多个阻塞的fd统一进行阻塞,其具体操作,以recv的操作为例总结如下:

FD_SET readSet;  //fd的集合
FD_ZERO(&readSet); //初始化
while(1)
{
        for(i=0; iif (pM->confd[i] >0)
            {
                FD_SET(pM->confd[i],&readSet); 
                /*其中pM->confd[i]为accept之后得到的fd,
                *全部设置到监控fd的集合中
                */
            }
        }
        int ret=select(0,&readSet,NULL,NULL,NULL); 
        /*有一个或多个fd接收到了数据,假设是n个,
        *这时readSet已经发生了变化,仅剩n个fd在集合中
        */
        for(i=0; iif(FD_ISSET(pM->confd[i],&readSet)) 
            /*判断有哪n个fd在集合中,这n个fd接收到了数据*/
            {
                recvLength =recv(pM->confd[i],commandString,COMLENGTH,0);
                /*直接调用recv,无需阻塞,正如《unix网络编程》所说,
                *省去了等待数据到来的阻塞,其实fd的连接只有一个的话,
                *直接调recv与select的结果一致的。
                */
                if (recvLength >0)
                {
                    printf("recv:%s\n",commandString);
                    memset(commandString,0,COMLENGTH);
                    SetEvent(pM->conEvent);
                }
            }
        }
        //循环,继续监听各个accept之后得到的fd
}

总结关键步骤:

  1. FD_SET(pM->confd[i],&readSet);//监听所有感兴趣的连接。
  2. int ret=select(0,&readSet,NULL,NULL,NULL);//有n个接受到数据,readSet仅剩这n个fd。
  3. FD_ISSET(pM->confd[i],&readSet);//得到这n个连接,并进行recv。

你可能感兴趣的:(网络)