Reputation: 954
I'm new in C and especially with threads.I've read some topics about this kind of problem but none of them worked for me. Here is my code:
#include <stdio.h>
#include <string.h> /* memset() */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <pthread.h>
#define PORT "7890" /* Port to listen on */
#define BACKLOG 10 /* Passed to listen() */
#define MAX_THREADS 100
//function that dumps buffer
void dump(const unsigned char *data_buffer, const unsigned int length){
unsigned char byte;
unsigned int i, j;
for(i=0; i < length; i++)
{
byte = data_buffer[i];
printf("%02x ", data_buffer[i]); // Display byte in hex.
if(((i%16)==15) || (i==length-1)) {
for(j=0; j < 15-(i%16); j++)
printf(" ");
printf("| ");
for(j=(i-(i%16)); j <= i; j++) { // Display printable bytes from line.
byte = data_buffer[j];
if((byte > 31) && (byte < 127)) // Outside printable char range
printf("%c", byte);
else
printf(".");
}
printf("\n"); // End of the dump line (each line is 16 bytes)
} // End if
} // End for
}
//thread handler
void *handle(void *pnewsock)
{
int *sock = (int*)pnewsock;
char buf[1024];
while(recv(*sock, buf, 1024, 0) > 0)
{
printf("Inside...");
dump(buf, strlen(buf));
memset(buf, '\0', 1024);
}
printf("Outside...");
return NULL;
}
int main(void)
{
int sock;
pthread_t thread[MAX_THREADS];
struct addrinfo hints, *res;
int reuseaddr = 1; /* True */
//struct user client;
/* Get the address info */
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(NULL, PORT, &hints, &res) != 0) {
perror("getaddrinfo");
return 1;
}
/* Create the socket */
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock == -1) {
perror("socket");
return 1;
}
/* Bind to the address */
if (bind(sock, res->ai_addr, res->ai_addrlen) == -1) {
perror("bind");
return 0;
}
freeaddrinfo(res);
/* Listen */
if (listen(sock, BACKLOG) == -1) {
perror("listen");
return 0;
}
size_t size = sizeof(struct sockaddr_in);
struct sockaddr_in their_addr;
int newsock;
printf("Waiting.\n");
int thread_counter = 0;
/* Main loop */
while (1)
{
newsock = accept(sock, (struct sockaddr*)&their_addr, &size);
if (newsock == -1)
{
perror("accept");
}
else
{
printf("Got a connection from %s on port %d\n",
inet_ntoa(their_addr.sin_addr), htons(their_addr.sin_port));
if (pthread_create(&thread[thread_counter], NULL, handle, &newsock) != 0)
{
fprintf(stderr, "Failed to create thread\n");
}
thread_counter++;
}
}
close(sock);
return 0;
}
So this is my server. I'm connecting it with telnet(I know that it's not secure but its for educational purposes). When multiple users are connected they start writing some things and server displays that(with dump function). But suddenly server stops to accept their messages and displays nothing. I print out some strings for debuging but it shows that threads don't leave while loop. But the problem is that they don't stay in while loop neither because string Inside... is not printing. I can't figure out what happens. thanks.
Upvotes: 1
Views: 187
Reputation: 5290
You are changing the value of newsock
in the main, after the address of that variable is passed to the created thread. In other words, the same variable is used in multiple threads, creating inconsistent results.
Make sure that when you create a thread, the passed address points to a variable that is only passed to that thread.
Upvotes: 2