#include "../basic.h" #include void sigpipeaction (int signal){ //fprintf(stderr, "Sigpipe catturato\n"); } typedef struct message { char data[100]; }t_message; int main(int argc, char **argv) { int listenfd, connfd, n; struct sockaddr_in servaddr; struct sockaddr_in client_address_struct; unsigned int client_address_struct_size = sizeof (client_address_struct); //////////////////////////////////////////////////////////// SIGNALS ///////SIGPIPE struct sigaction sigpipestructure; sigpipestructure.sa_handler = sigpipeaction; sigpipestructure.sa_flags = 0; sigaction (SIGPIPE, &sigpipestructure, NULL); //////////////////////////////////////////////////////////// END SIGNALS if (argc != 2 ){ printf("usage: daytimesrv \n"); exit(0); } if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("socket error\n"); exit(0); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* wildcard address */ servaddr.sin_port = htons(atoi(argv[1])); /* server port */ if( (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0){ printf("bind error\n"); exit(0); } if( listen(listenfd, 5) < 0 ){ printf("listen error\n"); exit(0); } fd_set fd_set_1; FD_ZERO(&fd_set_1); /* void FD_CLR(int fd, fd_set *set); int FD_ISSET(int fd, fd_set *set); void FD_SET(int fd, fd_set *set); void FD_ZERO(fd_set *set); */ struct timeval timer; timer.tv_sec = 99999999; timer.tv_usec = 0; int clients [FD_SETSIZE - 3]; int i; for (i= 0;i< (FD_SETSIZE - 3);i++){ *(clients + i) = -1 ; } // FD_SET(fileno(stdin),&fd_set_1); // control stdin (fileno = 0) // add listenfd to monitor listen socket FD_SET(listenfd,&fd_set_1); fprintf(stdout,"Added listen socket %d to monitor\n",listenfd ); int max_fd = listenfd + 1; t_message m; fd_set backup_set; for ( ; ; ) { fprintf(stdout,"waiting for non blocking fds\n"); int ready_fds_to_read = 0; backup_set = fd_set_1; for (ready_fds_to_read = select( max_fd, &fd_set_1, NULL,NULL,&timer); ready_fds_to_read <= 0 ; ready_fds_to_read = select( max_fd, &fd_set_1, NULL,NULL,&timer)){ if (ready_fds_to_read == -1 && errno == EINTR ){ continue;} if (ready_fds_to_read == 0) {timer.tv_sec = 99999999;continue;} // write code to inform client that server has an internal error exit(0); }// wait for nonblocking fd in read set fprintf(stdout,"ready: %d\n",ready_fds_to_read); int flag = 0; if (FD_ISSET(listenfd,&fd_set_1)){ ready_fds_to_read--; for ( ; ; ) { if( (connfd = accept(listenfd, (struct sockaddr *) &client_address_struct, &client_address_struct_size)) < 0) { if(errno == EINTR ) continue; printf("accept error on listening socket\n"); flag = 1; break; } break; } if (flag == 0){ /// operations on connfd int free = 0; for (i= 0;i< (FD_SETSIZE - 3);i++){ if (*(clients + i) == -1) {*(clients + i) = connfd; free = 1; break;} } if (free == 0){ shutdown (connfd, SHUT_RDWR); fprintf(stdout,"Can't server %d. Too many connected clients\n",connfd ); }else { FD_SET(connfd,&backup_set); max_fd = MAX(connfd + 1, max_fd); fprintf(stdout,"Added connection socket %d to monitor\n",connfd ); } } } // operations on other ready to read sockets in select int ready_fd, ready_fd_index; for (i= 0; i< (FD_SETSIZE - 3) && ready_fds_to_read>0; i++){ if ( *(clients + i) != -1 && FD_ISSET(*(clients + i),&fd_set_1)){ ready_fds_to_read--; ready_fd = *(clients + i); ready_fd_index = i; int ridden; for (ridden = read (ready_fd,&m,sizeof(m)); ridden <= 0;ridden = read (ready_fd,&m,sizeof(m))){ if (errno == EINTR){continue;} else {break;} } int written; if (ridden > 0){ fprintf(stdout,"%s from socket id %d\n",m.data,ready_fd); for (written = write (ready_fd,&m,sizeof(m)); written <= 0;written = write (ready_fd,&m,sizeof(m))){ if (errno == EINTR){continue;} else {break;} } } // test if client has received the packet and exit(); //the client implementation should only make a read after the server // write and exit for (ridden = read (ready_fd,&m,sizeof(m)); ridden <= 0;ridden = read (ready_fd,&m,sizeof(m))){ if (errno == EINTR){continue;} else {break;} } if (ridden> 0) {fprintf(stdout,"client from socket id %d should be dead\n",ready_fd);} shutdown (ready_fd, SHUT_RDWR); // SHUT_RD - SHUT_WR FD_CLR(ready_fd, &backup_set); clients[ready_fd_index] = -1; fprintf(stdout,"shutdown socket id %d\n",ready_fd); } } fd_set_1 = backup_set; } exit(0); }