Chatroom in C / Socket Programming on Linux

I have a simple server and client C code to make a chat for multi-clients using threads (pthread library). The problem I am facing is that I cannot imagine a way to get the server to write every message that the client sends over the socket to all other clients. Here I read other similar notes, and it was helpless. Please help me, I need to do this for school. I will send both codes at once.

Server.c:

#include<stdio.h> #include<string.h> //strlen #include<stdlib.h> //strlen #include<sys/socket.h> #include<arpa/inet.h> //inet_addr #include<unistd.h> //write #include<pthread.h> //for threading , link with lpthread void *connection_handler(void *); int main(int argc , char *argv[]) { int socket_desc , new_socket , c , *new_sock; struct sockaddr_in server , client; char *message; //Create socket socket_desc = socket(AF_INET , SOCK_STREAM , 0); if (socket_desc == -1) { printf("Could not create socket"); } //Prepare the sockaddr_in structure server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons( 8888 ); //Bind if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) { puts("bind failed"); return 1; } puts("bind done"); //Listen listen(socket_desc , 3); //Accept and incoming connection puts("Waiting for incoming connections..."); c = sizeof(struct sockaddr_in); while( (new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ) { puts("Connection accepted"); pthread_t sniffer_thread; new_sock = malloc(1); *new_sock = new_socket; if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0) { perror("could not create thread"); return 1; } //Now join the thread , so that we dont terminate before the thread //pthread_join( sniffer_thread , NULL); puts("Handler assigned"); } if (new_socket<0) { perror("accept failed"); return 1; } return 0; } /* * This will handle connection for each client * */ void *connection_handler(void *socket_desc) { //Get the socket descriptor int sock = *(int*)socket_desc; int read_size; char *message , client_message[2000]; //Receive a message from client while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 ) { //Send the message back to client write(sock , client_message , strlen(client_message)); } if(read_size == 0) { puts("Client disconnected"); fflush(stdout); } else if(read_size == -1) { perror("recv failed"); } //Free the socket pointer free(socket_desc); return 0; } 

Client.c

 #include<stdio.h> //printf #include<string.h> //strlen #include<sys/socket.h> //socket #include<arpa/inet.h> //inet_addr int main(int argc , char *argv[]) { int sock; struct sockaddr_in server; char message[1000] , server_reply[2000]; //Create socket sock = socket(AF_INET , SOCK_STREAM , 0); if (sock == -1) { printf("Could not create socket"); } puts("Socket created"); server.sin_addr.s_addr = inet_addr("127.0.0.1"); server.sin_family = AF_INET; server.sin_port = htons( 8888 ); //Connect to remote server if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) { perror("connect failed. Error"); return 1; } puts("Connected\n"); puts("Bienvenido al Chatroom, puedes empezar a escribir en la sala!"); //keep communicating with server while(1) { printf("Enter message: "); fgets(message, sizeof(message),stdin); //scanf("%s" , message); //Send some data if( send(sock , message , strlen(message) , 0) < 0) { puts("Send failed"); return 1; } //Receive a reply from the server if( recv(sock , server_reply , 2000 , 0) < 0) { puts("recv failed"); break; } printf("Server Reply: %s\n", server_reply); server_reply[0]='\0'; } close(sock); return 0; } 

These programs are very simple, the client sends what the user writes to the console, and the server sends the same message back. I just need a server to send the same message to every connected thread (client) (and not just to the one who sent the original message).

I know this is a long time for those who care, but if you can, I will be happy to receive help :)

+6
source share
1 answer

You need a global table of all clients protected by a mutex. When a new client connects, add them to the global client table. When the client disconnects, delete them from the global table.

When a client sends a message, acquire a lock in the global table and navigate to it. Send the message to all clients (except those who sent the message if you do not want the echo of the message to be returned to its source).

This is a gross simplification of how real servers do it. But that should be enough to get you started.

+5
source

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


All Articles