关于select的基础知识
a. select是系统提供的多路复用输入输出模型。它是用来监视多个文件句柄的状态变化。
b. 程序会停在select等,直到被监视的文件句柄至少有一个发生了状态改变。
c. 文件句柄是整数
函数
a. 参数
nfds:需要监视的最大文件描述符值加1;
struct timeval结构用于描述一段时间长度,若超出这个时间,需要监视的描述符没有发生,则返回0。
3.代码实现
21 // 22 int sock=socket(AF_INET,SOCK_STREAM,0); 23 if(sock<0) 24 { 25 perror("socket"); 26 exit(1); 27 } 28 // 28 // 29 struct sockaddr_in local; 30 local.sin_family=AF_INET; 31 local.sin_port=htons(port); 32 local.sin_addr.s_addr=inet_addr(ip); 33 // 34 if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0) 35 { 36 perror("bind"); 37 exit(2); 38 } 39 // 40 if(listen(sock,_BACKLOG_)<0) 41 { 42 perror("listen"); 43 exit(3); 44 } 45 return sock; 46 } 47 int main(int argc,char*argv[]) 48 { 49 if(argc!=3) 50 { 51 usage(argv[0]); 52 exit(1); 53 } 54 55 char* ip=argv[1]; 56 int port=atoi(argv[2]); 57 58 int listen_sock=startup(ip,port); 59 60 int done=0; 61 int new_sock=-1; 62 struct sockaddr_in client; 63 socklen_t len=sizeof(client); 64 65 int max_fd; 66 fd_set _reads; 67 fd_set _writes; 68 69 int i=0; 70 int fds_num=sizeof(fds)/sizeof(fds[0]); 71 for(;i<fds_num;++i) 72 { 73 fds[i]=-1; 74 } 75 fds[0]=listen_sock; 76 max_fd=fds[0]; 77 78 while(!done) 79 { 80 FD_ZERO(&_reads); 81 FD_ZERO(&_writes); 82 FD_SET(listen_sock,&_reads); 83 struct timeval _timeout={5,0}; 84 for(i=1;i<fds_num;++i) 85 { 86 if(fds[i]>0) 87 { 88 FD_SET(fds[i],&_reads); 89 if(fds[i]>max_fd) 90 { 91 max_fd=fds[i]; 92 } 93 } 94 } 95 switch(select(max_fd+1,&_reads,&_writes,NULL,NULL)) 96 { 97 case 0: 98 //timeout 99 printf("timeout\n"); 100 break; 101 case -1: 102 perror("select"); 103 break; 104 default: 105 { 106 i=0; 107 for(;i<fds_num;++i) 108 { 109 if(fds[i]==listen_sock&&FD_ISSET(fds[i],&_reads)) 110 { 111 //listen socket is ready! 112 new_sock=accept(listen_sock,(struct sockaddr*)&client,&len); 113 if(new_sock<0) 114 { 115 perror("accept"); 116 continue; 117 } 118 printf("get a new connect...%d\n",new_sock); 119 for(i=0;i<fds_num;++i) 120 { 121 if(fds[i]==-1) 122 { 123 fds[i]=new_sock; 124 break; 125 } 126 } 127 if(i==fds_num) 128 { 129 close(new_sock); 130 } 131 } 132 //listen socket 133 else if(fds[i]>0 && FD_ISSET(fds[i],&_reads)) 134 { 135 char buf[1024]; 136 ssize_t _s=read(fds[i],buf,sizeof(buf)-1); 137 if(_s>0) 138 { 139 //read sucess 140 buf[_s]=‘\0‘; 141 printf("client:%s\n",buf); 142 } 143 else if(_s==0) 144 { 145 //client shutdown 146 printf("client shutdown...\n"); 147 close(fds[i]); 148 fds[i]=-1; 149 } 150 else 151 { 152 perror("read"); 153 } 154 } 155 //normal socket 156 else 157 {} 158 } 159 } 160 break; 161 } 162 } 163 return 0; 164 }
本文出自 “sunshine225” 博客,请务必保留此出处http://10707460.blog.51cto.com/10697460/1784034
原文地址:http://10707460.blog.51cto.com/10697460/1784034