#include "TCPEchoServer.h" /* TCP echo server includes */ #include /* for POSIX threads */ void *ThreadMain(void *arg); /* Main program of a thread */ /* Structure of arguments to pass to client thread */ struct ThreadArgs { int clntSock; /* Socket descriptor for client */ }; int main(int argc, char *argv[]) { int servSock; /* Socket descriptor for server */ int clntSock; /* Socket descriptor for client */ unsigned short echoServPort; /* Server port */ pthread_t threadID; /* Thread ID from pthread_create() */ struct ThreadArgs *threadArgs; /* Pointer to argument structure for thread */ if (argc != 2) /* Test for correct number of arguments */ { fprintf(stderr,"Usage: %s \n", argv[0]); exit(1); } echoServPort = atoi(argv[1]); /* First arg: local port */ servSock = CreateTCPServerSocket(echoServPort); for (;;) /* run forever */ { clntSock = AcceptTCPConnection(servSock); /* Create separate memory for client argument */ if ((threadArgs = (struct ThreadArgs *) malloc(sizeof(struct ThreadArgs))) == NULL) DieWithError("malloc() failed"); threadArgs -> clntSock = clntSock; /* Create client thread */ if (pthread_create(&threadID, NULL, ThreadMain, (void *) threadArgs) != 0) DieWithError("pthread_create() failed"); printf("with thread %ld\n", (long int) threadID); } /* NOT REACHED */ } void *ThreadMain(void *threadArgs) { int clntSock; /* Socket descriptor for client connection */ /* Guarantees that thread resources are deallocated upon return */ pthread_detach(pthread_self()); /* Extract socket file descriptor from argument */ clntSock = ((struct ThreadArgs *) threadArgs) -> clntSock; free(threadArgs); /* Deallocate memory for argument */ HandleTCPClient(clntSock); return (NULL); }