select服务器

xiaoxiao2021-02-27  186

#include<stdio.h> #include<sys/socket.h> #include<sys/types.h> #include<netinet/in.h> #include<arpa/inet.h> #include<sys/select.h> #include<stdlib.h> #include<unistd.h> int fds[sizeof(fd_set)*8]; static void usage(const char *proc) { printf("%s [local_ip] [local_port]\n",proc); } int startup(const char *ip,int port) { int sock = socket(AF_INET,SOCK_STREAM,0); if(sock < 0) { perror("sock"); exit(2); } int opt = 1; setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); struct sockaddr_in local; local.sin_family = AF_INET; local.sin_port = htons(port); local.sin_addr.s_addr = inet_addr(ip); if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0) { perror("bind"); exit(3); } if(listen(sock,10) < 0) { perror("listen"); exit(4); } return sock; } int main(int argc,char *argv[]) { if(argc != 3) { usage(argv[0]); return 1; } int listen_sock = startup(argv[1],atoi(argv[2]));// listen a link just like care read events int nums = sizeof(fds)/sizeof(fds[0]); int i = 0;//set array start_value for(;i < nums;++i) { fds[i] = -1; } fds[0] = listen_sock; fd_set rfds; while(1) { int maxfd = -1; struct timeval timeout = {2,0}; FD_ZERO(&rfds); i = 0; for(;i < nums;++i) //set fd_set and find maxfd { if(fds[i] == -1) { continue; } FD_SET(fds[i],&rfds); if(maxfd < fds[i]) { maxfd = fds[i]; } } switch(select(maxfd+1,&rfds,NULL,NULL,NULL)) { case -1: break; case 0: printf("timeout....\n"); break; default://at least one fd ready { i = 0; for(;i < nums;++i) { if(i == 0&&FD_ISSET(fds[i],&rfds))//have ready,can start to accept { struct sockaddr_in client; socklen_t len = sizeof(client); int new_socket = accept(listen_sock,(struct sockaddr*)&client,&len);//can not blocked if(new_socket < 0) { perror("accept"); continue; } printf("get a client: [%s:%d]\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port)); int j = 1; for(;j < nums;++j) { if(fds[j] == -1) //find a position for new_socket,if new_socket ready,start to write/read { break; } } if(j == nums) { close(new_socket); //the fd_set is full,can not handler this link,close it } else { fds[j] = new_socket; } } else if(i != 0&&FD_ISSET(fds[i],&rfds)) //new_socket ready ,start to write/read ,not be blocked { char buf[1024]; ssize_t s = read(fds[i],buf,sizeof(buf)-1); if(s > 0) { buf[s] = 0; printf("client#%s\n",buf); } else if(s == 0) { printf("client is quit!!!\n"); close(fds[i]); //not only close this link fds[i] = -1; //but also set the array,next run do not care the fds } else { perror("read"); close(fds[i]); fds[i] = -1; } } } } } } return 0; }
转载请注明原文地址: https://www.6miu.com/read-7435.html

最新回复(0)