#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <stdio.h>#include <iostream>#include <errno.h>#include <string.h>#include <string>#include <time.h>#include <signal.h>#include <pthread.h>#include <sys/select.h>#define THREAD_NUM 1024static unsigned int recv_bytes[THREAD_NUM]={0};static unsigned int thread_number=0;static struct sigaction sa,sa_old;struct thread_argument{ int fd; int number;};static bool to_listen=true;void server(int fd,std::string host_ip,short host_port);void signal_handler(int){ unsigned int bytes=0; int i; for(i=0;i<thread_number && thread_number<THREAD_NUM;++i) { bytes+=recv_bytes[i]; } fprintf(stderr,"\nbytes=%u\n",bytes); to_listen=false; sigaction(SIGINT,&sa_old,NULL);}void * thread_routine(void *p){ int client_sockfd=(*(thread_argument *)p).fd; int number=(*(thread_argument *)p).number; const ssize_t RECV_SIZE=1024*32; char data[RECV_SIZE]={0}; int ret; while(1) { ret=read(client_sockfd, data,RECV_SIZE); if(-1==ret) { if(EINTR==errno || EWOULDBLOCK==errno) { continue; } else { fprintf(stderr,"%s\n",strerror(errno)); break; } } else if(0==ret) { fprintf(stderr,"thread %d recv over.\n",number+1); break; } if(number<THREAD_NUM) { recv_bytes[number]+=ret; } else { fprintf(stderr,"warning: THREAD_NUM too samll\n"); } } close(client_sockfd); delete (struct thread_argument *)p;}int main(int n,char *arg[]){ sa.sa_handler=signal_handler; sigaction(SIGINT,&sa,&sa_old); if(3!=n) { fprintf(stderr,"usage ./server + host ip + port\n"); return -1; } std::string host_ip=std::string(arg[1]); short host_port=static_cast<short>(atoi(arg[2])); int server_sockfd; server_sockfd=socket(AF_INET,SOCK_STREAM,0); if(-1==server_sockfd) { fprintf(stderr,"%s\n",strerror(errno)); return -1; } server(server_sockfd,host_ip,host_port); close(server_sockfd); return 0;}void server(int fd,std::string host_ip,short host_port){ int reuse_addr=1; if(-1==setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(const char*)&reuse_addr,sizeof(int))) { fprintf(stderr,"%s\n",strerror(errno)); return; } int recv_buf=32*1024; if(-1==setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const char*)&recv_buf,sizeof(int))) { fprintf(stderr,"%s\n",strerror(errno)); return; } struct sockaddr_in server_addr; server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=inet_addr(host_ip.c_str()); server_addr.sin_port=htons(host_port); if(-1==bind(fd,(struct sockaddr *)&server_addr,sizeof(server_addr))) { fprintf(stderr,"%s\n",strerror(errno)); return; } if(-1==listen(fd,22)) { fprintf(stderr,"%s\n",strerror(errno)); return; } int client_sockfd; struct sockaddr_in client_addr; socklen_t len=sizeof(client_addr); fd_set read_set; struct timeval timeout; timeout.tv_sec=2; timeout.tv_usec=0; while(to_listen) { FD_ZERO(&read_set); FD_SET(fd,&read_set); if(-1==select(fd+1,&read_set,NULL,NULL,&timeout)) { if(errno==EINTR) { continue; } else { fprintf(stderr,"%s\n",strerror(errno)); return; } } if(!FD_ISSET(fd,&read_set)) { continue; } client_sockfd=accept(fd,(struct sockaddr *)&client_addr,&len); if(-1==client_sockfd) { fprintf(stderr,"%s\n",strerror(errno)); return; } struct thread_argument *p_arg=new struct thread_argument; if(NULL==p_arg) { fprintf(stderr,"%s\n",strerror(errno)); return; } memset(p_arg,0,sizeof(struct thread_argument)); p_arg->fd=client_sockfd; p_arg->number=thread_number; pthread_t thread; if(0!=pthread_create(&thread,NULL,thread_routine,p_arg)) { fprintf(stderr,"%s\n",strerror(errno)); delete p_arg; return; } if(0!=pthread_detach(thread)) { fprintf(stderr,"%s\n",strerror(errno)); delete p_arg; return; } thread_number++; }//while}