linux select代码框架

#define PORT  1234
#define BACKLOG 5
#define MAXDATASIZE 1000
typedef struct CLIENT{
   int fd;
   char* name;
   struct sockaddr_in addr;//addr用client_addr更加准确
   char*data;
   };
 void main(){
 int i,maxi,maxfd,sockfd;
 in nready;
 fd_set rset,allset;//allset是我们要监控的fd集合,由于每次调用select都会更改监控的fd集合状态,所以再次调用的时候,需要重新设置fd集合,这里可以用allset保持监控集合,每次调用的时候用rset。改变的只是rset
 ssize_t n;
 int listenfd.connfd;
 struct sockaddr_in server_addr, client_addr;//注意,这里我们把client端的信息保存在CLIENT结构体中,
 CLIENT client[FD_SETSIZE];//FD_SETSIZE是宏常量
 char buf[MAXDATASIZE];
 int sin_size;
 if(listenfd=socket(AF_INET,SOCK_STREAM,0)==-1){
   perror("create socket failed");
   exit(1);
   }
 bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(PORT);
server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(listenfd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr)==-1)
 {  perror("bind socket failed");
   exit(1);
   }
if(listen(listenfd,BACKLOG)==-1)
{  perror("listen socket failed");
   exit(1);
} 
sin_size=sizeof(struct sockaddr_in)  


maxfd=listenfd;//最大的文件描述符
maxi=-1;  //最大的用过的CLIENT数组下标
for(i=0;i<FD_SETSIZE;i++){
   client[i].fd=-1;
 }//初始化client数组
 FD_ZERO(&allset);
 FD_SET(listenfd,&allset);//加入监听
 
while(1){
 struct sockaddr_in addr;  //用于返回client端的信息
 rset=allset;// 再次重新赋值
 nready=select(maxfd+1,&rset,NULL,NULL,NULL)//这测试FD读就绪,写的fdset为NULL
 
  if(FD_ISSET(listenfd,&allset)){   //new client connection 
    if((connfd=accept(listenfd,(struct sockaddr*)&addr,&sin_size))==-1)
      {    perror("accept() error\n");
           exit(1);
           continue;
        }
  for(i=0;i<FD_SETSIZE;i++)
     if(client[i].fd<0){
         client[i].fd=connfd;
         client[i].name=new char[MAXDATASIZE];
         client[i].addr=addr;//客服端的socket地址信息
          printf(" you got a connection from client");
         break;
       }
       
   if(i==FD_SETSIZE)  printf("too many connection")//;连接数的FD已经超过最大的1024
   FD_SET(connfd,&allset);//把connfd加入监听集合中
   if(connfd>maxfd)  maxfd=connfd;//更新目前最大的FD;
   if(i>maxi)   maxi=i;
   if(--nready<=0) continue;//之前select返回的时候只有一个监听listen是就绪的,则继续循环while(1),下面的程序不执行
   }       //对应 if(FD_ISSET(listenfd,&allset))     
   for(i=0;i<=maxfd;i++){
     if((sockfd=client[i].fd<0)) continue;
     if(FD_ISSET(sockfd,&rset)){//分两种情况,一种是此FD由于关闭连接,而变成可读
       if( (n=recv(sockfd,recvbuf,MAXDATASIZE,0))==0){
                close(sockfd);//关闭这个连接对应服务器的连接socket
                FD_CLR(sockfd,&allset);//从监控的FD集合中删除
                ..................
                 ...................
         }
       else   
         process(&client[i],revbuf,n)//否则就是读就绪,进行我们的操作
       if(--nready<=0) break;//处理完了所有的就绪描述符
    }
  }
 }
 close(listenfd);//调出while
}   
      
        

 

posted @ 2015-04-26 16:46  kkshaq  阅读(652)  评论(0编辑  收藏  举报