Multithreaded TCP Server in C

int sock, connected, bytes_received, true = 1; struct sockaddr_in server_addr, client_addr; int sin_size; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Socket"); exit(1); } if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &true, sizeof (int)) == -1) { perror("Setsockopt"); exit(1); } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(atoi(argv[1])); server_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(server_addr.sin_zero), 8); if (bind(sock, (struct sockaddr *) &server_addr, sizeof (struct sockaddr)) == -1) { perror("Unable to bind"); exit(1); } if (listen(sock, 5) == -1) { perror("Listen"); exit(1); } printf("\nTCPServer Waiting for client on port 5003"); fflush(stdout); while (1) { pthread_t *child = (pthread_t *)malloc( sizeof(pthread_t) ); sin_size = sizeof (struct sockaddr_in); connected = accept(sock, (struct sockaddr *) &client_addr, &sin_size); printf("\n I got a connection from (%s , %d)\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); pthread_create(child, NULL, interpretMessage, NULL); free(child); } 

My TCP server is listening on port 5003. When the connection is completed, I want to create a stream and run the interpMessage function. I have a few questions about this ...

1) Am I making a malloc call and for free in the right places?

2) After calling pthread_create, my code immediately goes to "free (child)"; and then back to the beginning of the while loop?

3) What happens if 5 people connect at the same time (how does the code work to create 5 threads?)

+4
source share
1 answer

Your code correctly uses malloc and free , but the way you do it makes the implementation more complicated than necessary. The pthread_create function works by writing the identifier of the new thread to the memory pointed to by the first parameter. In your case, you dynamically allocated this buffer, and then immediately freed it. Therefore, memory is bound to one iteration of the while . If this is what you want, you probably should just make a dedicated pthread_t stack and pass a pointer to it in pthread_create :

 while (1) { pthread_t child; /* ... */ pthread_create(&child, NULL, interpretMessage, NULL); } 

Now that child locally bound to a loop, memory management will be handled automatically without having to call malloc or free .

Regarding the second question of whether the control continues to be free (child) and then returns to the top of the loop after calling pthread_create , yes, thatโ€™s right. A second thread will be created that executes interpretMessage , so there may be some delay if the original process is delayed, but control resumes from this point.

For your last question, if five people all connect at exactly the same time, then the next five times you call accept , the function will provide one socket for the next incoming connection. That is, the OS will automatically place incoming connections in a certain order, and at each iteration of the loop, your code will notice that there is a connection, get a socket for it, and then cast the stream to process the message.

One thing that I noticed in your code is that when you create a thread to call interpretMessage , you did not specify any arguments to the function, and therefore each thread will work without any context for how it was created, Was it intentional?

+6
source

Source: https://habr.com/ru/post/1340871/


All Articles