0

I'm creating a client-server chat program in C using sockets and threads and having an issue implementing multi-threading. What I have currently got is a server that takes connections from clients using sockets that is working so far, the issue is when I try create multiple threads to handle sending and receiving.

When a client successfully connects to the server socket a thread is created in the client that handles receiving a message 'connected to server id: x', before it reaches the main while loop of the client program.

When a client reaches the server, a thread is created in the server to handle sending that data.

They seem to work okay but its the order of execution that is getting me. When I connect the client to the server what I thought would happen was the thread created to receive a message from the server would execute then the main while loop would. But instead it looks like the thread is waiting for main loop to take input.

// CURRENT CLIENT CODE - only including threading code
void * client_receive(void * sockID) {
 int network_socket = *((int *) sockID);
 while(1) {
 char data[1024];
 recv(network_socket, data, 1024, 0);
 printf("%s", data);
 }
}
int main() {
 pthread_t thread;
 pthread_create(&thread, NULL, client_receive, (void *) &network_socket);
 while(1) {
 printf("type a message: ");
 scanf("%s", message);
 send(network_socket, message, 1024, 0);
 }
}
________________________________________________________________________________
// CURRENT SERVER CODE
struct client {
 int index;
 int sockID;
 struct sockaddr_in clientAddr;
 int len;
};
void * client_interact(void * client_detail) {
 struct client* client_Detail = (struct client*) client_detail;
 int index = client_Detail -> index;
 int clientSocket = client_Detail -> sockID;
 index = index + 1;
 printf("Client connected");
 char message[1024] = "Welcome!";
 send(clientSocket, message, 1024, 0);
 while(1) {
 char receive[1024];
 recv(clientSocket, &receive, 1024, 0);
 printf("Client: %s", receive);
 }
}
struct client Client[1024];
pthread_t thread[1024];
int main() {
 while(1) {
 pthread_create(&thread[client_count], NULL, client_interact, (void *) &Client[client_count]);
 client_count++;
 }
 for (int i = 0; i < client_count; i++) {
 pthread_join(thread[i], NULL);
 }
 return 0;
}

Am I misunderstanding execution of threads? I thought that 'client_receive' would execute on the created thread before main printed 'type a message'

asked Oct 25, 2019 at 1:46
5
  • There's no synchronization between the client_receive and the main thread, so both will execute at the same time. So you might see them in either order. Commented Oct 25, 2019 at 2:19
  • Oh okay, would you suggest using a mutex lock? Commented Oct 25, 2019 at 2:29
  • Depends on what you're trying to do. If you want to fix the order, you could use some locks, but its probably easier to just not use threads. Commented Oct 25, 2019 at 2:57
  • Unfortunately its a requirement for this project. Although, the ordering at this point is annoying it doesn't explain the deadlock i'm getting Commented Oct 25, 2019 at 3:31
  • The code you've shown currently has no apparent deadlock problems -- you need to create a minimal reproducible example that shows how you're getting a deadlock. Commented Oct 25, 2019 at 17:02

1 Answer 1

1

It is not possible really to tell whether client_receive is being executed before the while loop in main; that is up to the scheduler to decide. However, client_receive will not print anything until some data is received from the socket, so unless your client sends your server some data, the client_receive function will block on the call to recv.

Hence, while it may seem like your program is waiting for an input before running client_receive, it could be that client_receive is blocking on the call to recv and your main thread is waiting for input.

In the case where your client is actually sending data over and your server doesn't seem to be responding to that data, it could be that there's some sort of buffering on your client's side. So make sure to flush your client's socket to force the data to be pushed to the server, causing recv to be called.


Side note: I'm assuming the code where you actually set up the socket connection and store the handle into network_socket has not been included for brevity, otherwise that could be an issue!

answered Oct 25, 2019 at 1:58
Sign up to request clarification or add additional context in comments.

4 Comments

I left the code that handles the socket off just to make it easier to read (should have been more clear). There seems to be a deadlock after initial connection, both server and client acknowledge connection but then nothing neither server or client will send or receive data until one of them is terminated, and then the other receives whatever data was sent
Have you tried flushing the socket on the client after sending data through it?
Yeah, neither will print anything just waiting for something I cant work out
Could you include your client code too? It could be something on that side possibly

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.