#include #include #include #include #include #include #include #include #include #include #include #include #include "errlib.h" #include "sockwrap.h" #define DEFAULT_PORT 12345 #define DEFAULT_CHILDREN 2 #define MAXBUFL 255 #define LISTENQ 15 //Struttura per PID figli typedef struct client { pid_t pid; }child; char *prog; int port, children, connection; //Array dinamico per PID figli child *queue=NULL; //Controllo correttezza parametri void check_args (int argc, char *argv[]) { switch (argc) { case 1: port=DEFAULT_PORT; children=DEFAULT_CHILDREN; break; case 2: if (sscanf(argv[1],"-p%d",&port)==1) { if (port<1024 || port>65536) { err_quit ("(%s) error - Port %d is not between 1024 - 65536\r\n", prog, port);//per porte alte sballa } children=DEFAULT_CHILDREN; break; } if (sscanf(argv[1],"-n%d",&children)==1) { if (children<0 || children>65536) { err_quit ("(%s) error - Children %d are not between 0 - 65536\r\n", prog, children); } port=DEFAULT_PORT; break; } if (sscanf(argv[1],"-n%d",&children)!=1 || sscanf (argv[1],"-p%d",&port)!=1){ err_quit ("Usage: %s [-nMAXCHILDRENNUMBER] [-pPORTNUMBER]", prog); break; } case 3: if (sscanf(argv[1],"-n%d",&children)==1) { if (children<0 || children>65536) { err_quit ("(%s) error - Children %d are not between 0 - 65536\r\n", prog, children); } if (sscanf(argv[2],"-p%d",&port)==1) { if (port<1024 || port>65536) { err_quit ("(%s) error - Port %d is not between 1024 - 65536\r\n", prog, port); } break; } } if (sscanf(argv[1],"-p%d",&port)==1) { if (port<1024 || port>65536) { err_quit ("(%s) error - Port %d is not between 1024 - 65536\r\n", prog, port); } if (sscanf(argv[2],"-n%d",&children)==1) { if (children<0 || children>65536) { err_quit ("(%s) error - Children %d are not between 0 - 65536\r\n", prog, children); } break; } } if(sscanf (argv[1],"-n%d",&children)!=1 || sscanf (argv[1],"-p%d",&port)!=1){ if(sscanf (argv[2],"-p%d",&port)!=1 || sscanf (argv[2],"-n%d",&children)!=1){ err_quit ("Usage: %s [-nMAXCHILDRENNUMBER] [-pPORTNUMBER]", prog); break; } } default: 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 //; // occhio a questo punto e virgola 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)// funziona? { int i; for (i=0; i 0) { char op1; int a, b, q; buf[n] = '\0'; //switch(nbyte) //{ //case 1: if (sscanf(buf,"%c %d %d",&op1,&a,&b) < 3 || sscanf(buf,"%c %d %d",&op1,&a,&b) > 3) { if (op1=='Q') { Close(connfd); } else snprintf (buf, sizeof(buf), "E\r\n"); } else { if(op1=='+') snprintf (buf, sizeof(buf), "=%d\r\n", a+b); if(op1=='-') snprintf (buf, sizeof(buf), "=%d\r\n", a-b); if(op1=='*') snprintf (buf, sizeof(buf), "=%d\r\n", a*b); if(op1=='/'){ q=a/b; if(q!=0) snprintf (buf, sizeof(buf), "=%d\r\n", a/b); else snprintf (buf, sizeof(buf), "U\r\n"); } } //break; //case 2: //break; Writen (connfd, buf, strlen(buf)); //} } } void hello (int connfd) { char buf[MAXBUFL]; size_t n; int byte=0;//mettere byte in uint8_t char ch; memset(buf, '\0', sizeof(buf));//? while ((n = Readline (connfd, buf, sizeof(buf)-1)) > 0)//legge oltre due dati { buf[n] = '\0'; if (sscanf(buf,"%c %d", &ch,&byte) < 2 || sscanf(buf,"%c %d", &ch,&byte) > 2) //if(n<2 || n>2) { if (ch=='Q') { Close(connfd); } else { snprintf (buf, sizeof(buf), "E\r\n"); Writen (connfd, buf, strlen(buf)); } } else { if (ch=='H') { if (byte == 1 || byte == 2) { snprintf (buf, sizeof(buf), "?\r\n"); Writen (connfd, buf, strlen(buf)); calc(connfd, byte); } else { snprintf (buf, sizeof(buf), "E\r\n"); Writen (connfd, buf, strlen(buf)); } } else { snprintf (buf, sizeof(buf), "E\r\n"); Writen (connfd, buf, strlen(buf)); } } } } int main (int argc, char *argv[]) { int listenfd, connfd; struct sockaddr_in servaddr, cliaddr; char buffer[MAXBUFL];//? socklen_t cliaddrlen; pid_t pid; uint8_t out=255, in=0; prog = argv[0]; check_args(argc, argv); queue = (child *) malloc(children*sizeof(child)); /*if(queue == NULL) { err_quit("(%s) error - Malloc failed\r\n", prog); }*/ memset ((void *) queue, 0, children*sizeof(child));//? memset(buffer, '\0', sizeof(buffer));//? listenfd = Socket (AF_INET, SOCK_STREAM, 0); 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) { snprintf (buffer, sizeof(buffer), "%u\r\n", out); Writen (connfd, buffer, strlen(buffer)); Close (connfd); } else { snprintf (buffer, sizeof(buffer), "%u\r\n", in); Writen (connfd, buffer, strlen(buffer)); if ((pid = Fork()) == 0) // this is the child { Close (listenfd); hello (connfd); Close (connfd); exit (0); } else // this is the parent { pid_queue(pid); Close (connfd); #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); }