Reputation: 163
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 listens on port 5003. When a connection is made, I want to spawn a thread and run the function interpretMessage. I have a few questions about this...
1) Am I doing calling malloc and free in the correct places?
2) After pthread_create is called, does my code immediately jump to "free(child);" and then back to the beginning of the while loop?
3) What happens if 5 people connect at the same exact time (how does the code run to spawn 5 threads?)
Upvotes: 4
Views: 13814
Reputation: 373462
Your code correctly does use malloc
and free
, but the way that you're doing so makes the implementation more complicated than is necessary. The pthread_create
function works by writing the ID of the new thread to the memory pointed at by its first parameter. In your case, you've dynamically allocated this buffer and then immediately freed it. Consequently, the memory is scoped to one iteration of the while
loop. If this is what you want, you're probably better off just making the pthread_t
stack-allocated and passing a pointer to it into pthread_create
:
while (1)
{
pthread_t child;
/* ... */
pthread_create(&child, NULL, interpretMessage, NULL);
}
Now that child
is locally-scoped to the loop, the memory management will be handled automatically without any need to call malloc
or free
.
As for your second question about whether the control continues to free (child)
and then back up to the top of the loop after the call to pthread_create
, yes, this is correct. A second thread will be created running interpretMessage
, so there may be some delay if the original process gets delayed, but control does resume from this point.
For your last question, if five people all connect at exactly the same time, then on the next five times you call accept
the function will provide a single socket for the next incoming connection. That is, the OS will automatically queue up the incoming connections into some order, and on each iteration of the loop your code will notice that there's a connection, get a socket for it, then spawn off a thread to process the message.
One thing I noticed in your code - when you're spawning off a thread to call interpretMessage
, you didn't provide any arguments to the function, and so each thread will operate without any context for how it was created. Was this intentional?
Upvotes: 5