void addfd(int epollfd, int fd){ struct epoll_event event; event.data.fd = fd; event.events = EPOLLIN | EPOLLET; epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event); setnoblocking(fd); }
int main(int argc,char* argv[]) { if(argc<=2) { printf("usage:%s ip_address port_number\n",basename(argv[0])); return 1; } const char *ip = argv[1]; int port = atoi(argv[2]); int sockfd = socket(AF_INET,SOCK_STREAM,0); assert(sockfd>=0); struct sockaddr_in address; bzero(&address,sizeof(address)); address.sin_family = AF_INET; address.sin_port = htons(port); inet_pton(AF_INET,ip,&address.sin_addr); int bind_ret = bind(sockfd,(struct sockaddr*)&address, sizeof(address)); assert(bind_ret!=-1); int listenfd = listen (sockfd,5); assert(listenfd!=-1); client_data * users = new client_data[FD_LIMIT]; pollfd fds[FD_LIMIT+1]; static int user_counter; for(int i=1;i<=USER_LIMIT;++i) { fds[i].fd = -1; fds[i].events = 0; } fds[0].fd = sockfd; fds[0].events = POLLIN|POLLERR; fds[0].revents = 0; while(1) { int poll_ret = poll(fds,user_counter+1,-1); if(poll_ret<0) { printf("poll failure\n"); break; } for(int i=0;i<user_counter+1;++i) { if((fds[i].fd == sockfd)&&(fds[i].revents&POLLIN)) { struct sockaddr_in client_address; socklen_t client_addlent = sizeof(client_address); int connfd = accept(sockfd,(struct sockaddr*)&client_address,&client_addlent); if(connfd<0) { printf("errno is:%d\n",errno); continue; } //if the requester too many ,close the new one; if(user_counter>=USER_LIMIT) { const char *info ="too many users\n"; printf("%s",info); send(connfd,info,strlen(info),0); close(connfd); continue; } user_counter++; users[connfd].address = client_address; setnoblocking(connfd); fds[user_counter].fd=connfd; fds[user_counter].events=POLLIN |POLLHUP |POLLERR; fds[user_counter].revents=0; printf("comes a new user, now have %d users\n",user_counter); } else if(fds[i].revents&POLLERR) { printf( "get an error from %d\n", fds[i].fd ); char errors[ 100 ]; memset( errors, '\0', 100 ); socklen_t length = sizeof( errors ); if( getsockopt( fds[i].fd, SOL_SOCKET, SO_ERROR, &errors, &length ) < 0 ) { printf( "get socket option failed\n" ); } continue; } else if(fds[i].revents&POLLRDHUP) { users[fds[i].fd]=users[fds[user_counter].fd]; close(fds[i].fd); fds[i] = fds[user_counter]; i--; user_counter--; printf("a user left\n"); } else if(fds[i].revents&POLLIN) { int connfd = fds[i].fd; memset( users[connfd].buf, '\0', BUFFER_SIZE ); int ret = recv( connfd, users[connfd].buf, BUFFER_SIZE-1, 0 ); //printf( "get %d bytes of client data %s from %d\n", ret, users[connfd].buf, connfd ); if( ret < 0 ) { if( errno != EAGAIN ) { close( connfd ); users[fds[i].fd] = users[fds[user_counter].fd]; fds[i] = fds[user_counter]; i--; user_counter--; } } else if( ret == 0 ) { //printf( "code should not come to here\n" ); } else { for( int j = 1; j <= user_counter; ++j ) { if( fds[j].fd == connfd ) { continue; } fds[j].events |= ~POLLIN; fds[j].events |= POLLOUT; users[fds[j].fd].write_buf = users[connfd].buf; } } } else if(fds[i].revents&POLLOUT) { printf("out out out out out out out out out out out out \n"); int connfd = fds[i].fd; if( ! users[connfd].write_buf ) { continue; } int ret = send( connfd, users[connfd].write_buf, strlen( users[connfd].write_buf ), 0 ); users[connfd].write_buf = NULL; fds[i].events |= ~POLLOUT; fds[i].events |= POLLIN; } } } delete [] users; close(sockfd); return 0; }
int main(int argc,char * argv[]){ if (argc <= 2){ printf("usage : ip port\n"); // return 1; } const char * ip = argv[1]; int port = atoi(argv[2]); struct sockaddr_in address; memset(&address,0,sizeof(address)); //address.sin_family = AF_INET; //inet_pton(AF_INET,ip,&address.sin_addr); //address.sin_port = htons(port); address.sin_family=AF_INET; address.sin_addr.s_addr=INADDR_ANY; address.sin_port=htons(8000); int listenfd = socket(PF_INET,SOCK_STREAM,0); assert(listenfd >= 0); int ret = bind(listenfd,(struct sockaddr * )&address,sizeof(address)); if (ret == -1){ perrmsg(errno); return 1; } ret = listen(listenfd,5); assert(ret != -1); struct epoll_event events[MAX_EVENT_NUMBER]; int epollfd = epoll_create(5); assert (epollfd != -1); addfd(epollfd,listenfd); ret = socketpair(PF_UNIX,SOCK_STREAM,0,pipefd); assert (ret != -1); setnoblocking(pipefd[1]); addfd(epollfd,pipefd[0]); addsig(SIGHUP); addsig(SIGCHLD); addsig(SIGTERM); addsig(SIGINT); int stop_server = 0; while(!stop_server){ int number = epoll_wait(epollfd,events,MAX_EVENT_NUMBER,-1); if ((number != 0) && ( errno != EINTR)){ printf ("epoll failed\n"); strerror(errno); } int i=0; for ( i; i< number; i++){ int sockfd = events[i].data.fd; if (sockfd = listenfd){ struct sockaddr_in client_address; socklen_t client_lenth = sizeof(client_address); int connfd = accept(listenfd,(struct sockaddr *)&client_address,&client_lenth); addfd(epollfd,connfd); } else if ((sockfd == pipefd[0]) && (events[i].events & EPOLLIN)){ int sig; char signals[1024]; ret = recv(pipefd[0],signals,sizeof(signals),0); if (ret == -1){ continue; } else if(ret == 0){ continue; } else{ int i; for ( i=0;i<ret;++i){ printf("sig no occured is %d",signals[i]); if (signals[i] == SIGINT){ stop_server = 1; } } } } } } printf("close fds\n"); close(listenfd); close(pipefd[0]); close(pipefd[1]); return 0; }