select多路IO复用
1、描述:接受多个客户端的连接请求,同时处理客户端的request
int listenfd = socket(PF_INET, SOCK_STREAM, 0);
if(listenfd == -1) {
printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
exit(-1);
}
struct sockaddr_in servaddr = {0};
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8888);
servaddr.sin_addr.s_addr = INADDR_ANY;
if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) {
printf("bind socket error: %s(errno: %d)\n", strerror(errno), errno);
exit(-1);
}
if(listen(listenfd, 1) == -1) {
printf("listen socket error: %s(errno: %d)\n", strerror(errno), errno);
exit(-1);
}
fd_set rfds, rtemp;
FD_ZERO(&rfds);
FD_ZERO(&rtemp);
FD_SET(listenfd, &rfds);
int maxfd = listenfd;
struct timeval timeout;
int nready;
while(1) {
timeout.tv_sec = 0;
timeout.tv_usec = 500;
rtemp = rfds;
nready = select(maxfd+1, &rtemp, NULL, NULL, &timeout);
if(FD_ISSET(listenfd, &rtemp)) {
int connfd = handle_connect(listenfd);
FD_SET(connfd, &rfds);
printf("=======client(%d) connected=======\n", connfd);
maxfd = (connfd > maxfd) ? connfd : maxfd;
if(--nready == 0) continue;
}
if(nready > 0) {
int i = 0;
for(i = listenfd+1; i<= maxfd; i++) {
if(FD_ISSET(i, &rtemp)) {
int result = handle_request(i);
if(result == -1) {
FD_CLR(i, &rfds);
close(i);
printf("=======client(%d) disconnected=======\n", i);
}
if(--nready == 0) break;
}
}
} else if(nready == 0) {
} else {
printf("select socket error: %s(errno: %d)\n", strerror(errno), errno);
break;
}
}
close(listenfd);
return 0;
}