/* * Homework 1 - Server * by Labianca Fabio Nino */ #include #include #include #include #include #include #include #include #include #include #include #include #include "errlib.h" #include "sockwrap.h" #include "mywrappers.h" #include "wrappers.h" #define DEFAULT_PORT 12345 #define DEFAULT_CHILDREN 2 #define MAXBUFL 255 #define LISTENQ 15 /* * Struttura per memorizzare PID dei figli */ typedef struct client { pid_t pid; }child; /* * Dichiarazione variabili globali */ child *queue=NULL; /* coda figli */ char *prog; int port=DEFAULT_PORT, children=DEFAULT_CHILDREN, connection=0; /* * Controllo che la stringa contenga solo numeri */ int check_num (char *s) { char temp_var[MAXBUFL]; int j=0; memset (temp_var, '\0', MAXBUFL); strncpy (temp_var, s, MAXBUFL-1); #ifdef TRACE err_msg ("(%s) info - Stringa %s | Lunghezza %d\r\n", prog, s, strlen(temp_var)); #endif for (j=0; j1) { for (i=1; i=65536) { #ifdef TRACE err_msg ("(%s) error - Port %d is not between 1024 - 65535\r\n", prog, port); #endif err_quit ("Usage: %s [-nMAXCHILDRENNUMBER] [-pPORTNUMBER]", prog); } status=1; } else { if ( (sscanf(argv[i],"-n%d",&children)==1) && ( status!=2 ) ) { check_num(argv[i]+2); if (children<=0 || children>=65536) { #ifdef TRACE err_msg ("(%s) error - Child %d is not between 1 - 65535\r\n", prog, children); #endif err_quit ("Usage: %s [-nMAXCHILDRENNUMBER] [-pPORTNUMBER]", prog); } status=2; } else err_quit ("Usage: %s [-nMAXCHILDRENNUMBER] [-pPORTNUMBER]", prog); } } } #ifdef TRACE err_msg ("(%s) info - TCP Port: %d\r\n", prog, port); err_msg ("(%s) info - Max Children number: %d\r\n", prog, children); #endif } /* * Inserimento PID dei figli nell'array */ void pid_queue(pid_t p) { int i=0; for (i=0; i 0) { #ifdef TRACE err_msg ("(%s) info - Child number %d (pid: %d) terminated with status %d\r\n", prog, connection, pid, status); #endif pid_unqueue(pid); } #ifdef TRACE err_msg ("(%s) info - Number of children currently connected: %d\r\n", prog, connection); #endif } void sigint_h (int signum) { #ifdef TRACE err_msg ("(%s) info - Server shut down\r\n", prog); #endif exit(0); } void sigterm_h (int signum) { int i; for (i=0; i 0) { ch = buf[0]; if (nbyte==1) { myReadn (connfd, buf, 2*sizeof(int8_t)); memcpy ((void *) &num1_8, buf, sizeof(int8_t)); memcpy ((void *) &num2_8, buf+sizeof(int8_t), sizeof(int8_t)); #ifdef TRACE err_msg("(%s) info - op: %c num1: %u num2: %u\r\n", prog, ch, (int8_t)num1_8, (int8_t)num2_8); #endif if(ch=='+') { //if ( (int)(num1_8+num2_8) != (int) ( (int8_t)(num1_8+num2_8) ) ) // { // memcpy (buf, "V", sizeof(char)); // Writen (connfd, buf, sizeof(char)); //} //else //{ //memcpy (buf, "=", sizeof(char)); ris8=(num1_8+num2_8); //memcpy (buf+sizeof(char), (void*)&ris8, sizeof(int8_t)); memcpy (buf, (void*)&ris8, sizeof(int8_t)); #ifdef TRACE err_msg("(%s) info - ris8: %u\r\n", prog, (int8_t)ris8); #endif //Writen (connfd, buf, sizeof(char)+sizeof(int8_t)); Writen (connfd, buf, sizeof(int8_t)); //} //break; /* switch(ch) { case '+': if ( (int)(num1_8+num2_8) != (int) ( (int8_t)(num1_8+num2_8) ) ) { memcpy (buf, "V", sizeof(char)); Writen (connfd, buf, sizeof(char)); } else { memcpy (buf, "=", sizeof(char)); ris8=(num1_8+num2_8); memcpy (buf+sizeof(char), (void*)&ris8, sizeof(int8_t)); Writen (connfd, buf, sizeof(char)+sizeof(int8_t)); } break; case '-': if ( (int)(num1_8-num2_8) != (int) ( (int8_t)(num1_8-num2_8) ) ) { memcpy (buf, "V", sizeof(char)); Writen (connfd, buf, sizeof(char));} else { memcpy (buf, "=", sizeof(char)); ris8=(num1_8-num2_8); memcpy (buf+sizeof(char), (void*)&ris8, sizeof(int8_t)); Writen (connfd, buf, sizeof(char)+sizeof(int8_t)); } break; case '*': if ( (int)(num1_8*num2_8) != (int) ( (int8_t)(num1_8*num2_8) ) ) { memcpy (buf, "V", sizeof(char)); Writen (connfd, buf, sizeof(char)); } else { memcpy (buf, "=", sizeof(char)); ris8=(num1_8*num2_8); memcpy (buf+sizeof(char), (void*)&ris8, sizeof(int8_t)); Writen (connfd, buf, sizeof(char)+sizeof(int8_t));} break; case '/': if ( (int8_t)num2_8==0 ) send_err(connfd); else if ( (int)(num1_8/num2_8) != (int) ( (int8_t)(num1_8/num2_8) ) ) { memcpy (buf, "V", sizeof(char)); Writen (connfd, buf, sizeof(char)); } else if ( ( (int8_t)num1_8==0) || ( ( (int8_t)(num1_8/num2_8) )==0 ) ) { memcpy (buf, "U", sizeof(char)); Writen (connfd, buf, sizeof(char)); } else { memcpy (buf, "=", sizeof(char)); ris8=(num1_8/num2_8); memcpy (buf+sizeof(char), (void*)&ris8, sizeof(int8_t)); Writen (connfd, buf, sizeof(char)+sizeof(int8_t)); } break;*/ //default: send_err(connfd); //break; } } if (nbyte==2) { myReadn (connfd, buf, 4); memcpy ((void *) &num1_16, buf, sizeof(uint16_t)); num1_16=ntohs(num1_16); memcpy ((void *) &num2_16, buf+sizeof(uint16_t), sizeof(uint16_t)); num2_16=ntohs(num2_16); #ifdef TRACE err_msg("(%s) info - op: %c num1: %u num2: %u\r\n", prog, ch, num1_16, num2_16); #endif switch(ch) { case '+': if ( (int)(num1_16+num2_16) != (int) ( (uint16_t)(num1_16+num2_16) ) ) memcpy (buf, "V", sizeof(char)); else { memcpy (buf, "=", sizeof(char)); ris16=htons(num1_16+num2_16); memcpy (buf+sizeof(char), (void*)&ris16, sizeof(uint16_t)); Writen (connfd, buf, sizeof(char)+sizeof(uint16_t)); } break; case '-': if ( (int)(num1_16-num2_16) != (int) ( (uint16_t)(num1_16-num2_16) ) ) { memcpy (buf, "V", sizeof(char)); Writen (connfd, buf, sizeof(char)); } else { memcpy (buf, "=", sizeof(char)); ris16=htons(num1_16-num2_16); memcpy (buf+sizeof(char), (void*)&ris16, sizeof(uint16_t)); Writen (connfd, buf, sizeof(char)+sizeof(uint16_t)); } break; case '*': if ( (int)(num1_16*num2_16) != (int) ( (uint16_t)(num1_16*num2_16) ) ) { memcpy (buf, "V", sizeof(char)); Writen (connfd, buf, sizeof(char)); } else { memcpy (buf, "=", sizeof(char)); ris16=htons(num1_16*num2_16); memcpy (buf+sizeof(char), (void*)&ris16, sizeof(uint16_t)); Writen (connfd, buf, sizeof(char)+sizeof(uint16_t)); } break; case '/': if ( (uint16_t)num2_16==0 ) send_err(connfd); else if ( (int)(num1_16/num2_16) != (int) ( (uint16_t)(num1_16/num2_16) ) ) { memcpy (buf, "V", sizeof(char)); Writen (connfd, buf, sizeof(char)); } else if ( ( (uint16_t)num1_16==0) || ( ( (uint16_t)(num1_16/num2_16) )==0 ) ) { memcpy (buf, "U", sizeof(char)); Writen (connfd, buf, sizeof(char)); } else { memcpy (buf, "=", sizeof(char)); ris16=htons(num1_16/num2_16); memcpy (buf+sizeof(char), (void*)&ris16, sizeof(uint16_t)); Writen (connfd, buf, sizeof(char)+sizeof(uint16_t)); } break; default: send_err(connfd); break; } } memset(buf, '\0', sizeof(buf)); } return; } /* * Funzione che invia msg di hello */ void hello (int connfd) { char buf[MAXBUFL],ch; size_t n; uint8_t byte=0; memset(buf, '\0', sizeof(buf)); while ((n = myReadn (connfd, buf, 1) > 0)) { ch=buf[0]; if (ch!=' ') { if (ch=='Q') return; if (ch=='H') { myReadn (connfd, buf, sizeof (uint8_t)); memcpy ((void *) &byte, buf, sizeof (uint8_t)); if (byte==1 || byte==2) { memset(buf, '\0', sizeof(buf)); snprintf (buf, sizeof(buf), "?\r\n"); Writen (connfd, buf, strlen(buf)); #ifdef TRACE err_msg("(%s) info - Numero catturato: %d - lancio Calcolo(); \r\n", prog, (uint8_t)byte); #endif calc(connfd, byte); } else send_err(connfd); }else send_err(connfd); }else send_err(connfd); } return; } /* * main function */ int main (int argc, char *argv[]) { /* identificatori dei socket */ int listenfd, connfd; /* dati connessioni */ struct sockaddr_in servaddr, cliaddr; char buffer[MAXBUFL]; socklen_t cliaddrlen; pid_t pid; uint8_t out=255, in=0; /* dati per la SETSOCKOPT */ int on=1; struct linger ling; prog = argv[0]; check_args(argc, argv); queue = (child *)Malloc(children*sizeof(child)); memset ((void *) queue, 0, children*sizeof(child)); memset(buffer, '\0', sizeof(buffer)); listenfd = Socket (AF_INET, SOCK_STREAM, 0); /* permette il riuso immediato di un indirizzo ip */ Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); ling.l_onoff=0; ling.l_linger=0; /* se rimangono dei dati sul canale in chiusura tenta di inviarli lo stesso */ Setsockopt(listenfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)); memset (&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(port); Bind (listenfd, (SA*) &servaddr, sizeof(servaddr)); Listen (listenfd, LISTENQ); #ifdef TRACE err_msg ("(%s) info - Socket created, waiting for connections ...\r\n", prog); #endif signal (SIGCHLD, sigchld_h); signal (SIGTERM, sigterm_h); signal (SIGINT, sigint_h); while (1) { cliaddrlen = sizeof(cliaddr); connfd = Accept (listenfd, (SA*) &cliaddr, &cliaddrlen); #ifdef TRACE err_msg ("(%s) info - New connection from client %s:%u\r\n", prog, inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port)); #endif if(connection>=children) { Writen (connfd, &out, sizeof(uint8_t));//IMP Close (connfd); } else { Writen (connfd, &in, sizeof(uint8_t)); if ((pid = myFork()) == 0) /* this is the child */ { Close (listenfd); signal(SIGCHLD, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGINT, SIG_DFL); hello (connfd); Close (connfd); exit (0); } else /* this is the parent */ { Close (connfd); pid_queue(pid); #ifdef TRACE err_msg ("(%s) info - Child number %d (pid:%d) spawned\r\n", prog, connection, pid); err_msg ("(%s) info - Waiting for HELLO from child number %d ...\r\n", prog, connection); #endif } } } exit (0); }