/* A threaded server in the internet domain using TCP The port number is passed as an argument */ #include #include #include #include #include #include #include #include #include #define BUFFERLENGTH 256 /* displays error messages from system calls */ void error(char *msg) { perror(msg); exit(1); } int isExecuted = 0; int returnValue; /* not used; need something to keep compiler happy */ pthread_mutex_t mut; /* the lock */ void *processRequest (void *args) { int newsockfd = *((int *) args); char buffer[BUFFERLENGTH]; int n; int tmp; n = read (newsockfd, buffer, BUFFERLENGTH -1); if (n < 0) error ("ERROR reading from socket"); printf ("Here is the message: %s\n",buffer); pthread_mutex_lock (&mut); /* lock exclusive access to variable isExecuted */ tmp = isExecuted; printf ("Waiting for confirmation: Please input an integer\n"); scanf ("%d", &n); /* not to be done in real programs: don't go to sleep while holding a lock! Done here to demonstrate the mutual exclusion problem. */ printf ("Read value %d\n", n); isExecuted = tmp +1; pthread_mutex_unlock (&mut); /* release the lock */ n = sprintf (buffer, "I got you message, the value of isExecuted is %d\n", isExecuted); /* send the reply back */ n = write (newsockfd, buffer, BUFFERLENGTH); if (n < 0) error ("ERROR writing to socket"); close (newsockfd); /* important to avoid memory leak */ returnValue = 0; /* cannot guarantee that it stays constant */ pthread_exit (&returnValue); } int main(int argc, char *argv[]) { size_t clilen; int sockfd, newsockfd, portno; char buffer[BUFFERLENGTH]; struct sockaddr_in serv_addr, cli_addr; pthread_t *server_thread; int result; if (argc < 2) { fprintf (stderr,"ERROR, no port provided\n"); exit(1); } /* create socket */ sockfd = socket (AF_INET, SOCK_STREAM, 0); if (sockfd < 0) error("ERROR opening socket"); bzero ((char *) &serv_addr, sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons (portno); /* bind it */ if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding"); /* ready to accept connections */ listen (sockfd,5); clilen = sizeof (cli_addr); /* now wait in an endless loop for connections and process them */ while (1) { /* waiting for connections */ newsockfd = accept( sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) error ("ERROR on accept"); bzero (buffer, BUFFERLENGTH); /* creaete separate thread for processing */ server_thread = malloc (sizeof (pthread_t)); if (!server_thread) { fprintf (stderr, "Couldn't allocate memory for thread!\n"); exit (1); } result = pthread_create (server_thread, NULL, processRequest, (void *) (&newsockfd)); if (result != 0) { fprintf (stderr, "Thread creation failed!\n"); exit (1); } } return 0; }