Ojs
Ojs

Reputation: 954

C: Simple chat program where users(Threads) can't send messages

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

Answers (1)

this
this

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

Related Questions