Client Initialization and Receive Thread
C
typedef struct { struct sockaddr_in serverAddr; int socket; } Client; Client client; void *receiveMessages( void *arg) { char buffer[MAX_MESSAGE_SIZE]; ssize_t bytesRead; while (1) { bytesRead = recvfrom(client.socket, buffer, sizeof (buffer), 0, NULL, NULL); if (bytesRead == -1) { perror ( "Receive failed" ); exit (EXIT_FAILURE); } buffer[bytesRead] = '\0' ; printf ( "Server: %s" , buffer); } } |
- Client Structure Definition: A structure (Client) is defined to hold information about the server address and the client socket.
- Client Initialization: An instance of the Client structure (client) is created to store client-related information.
- Receive Thread Function: The receiveMessages function is defined to handle continuous message reception from the server in a separate thread.
Step 3: Socket Creation and Message Sending
C
int main() { pthread_t receiveThread; char message[MAX_MESSAGE_SIZE]; ssize_t bytesRead; // Create socket if ((client.socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror ( "Socket creation failed" ); exit (EXIT_FAILURE); } // Configure server address memset (&client.serverAddr, 0, sizeof (client.serverAddr)); client.serverAddr.sin_family = AF_INET; client.serverAddr.sin_port = htons(PORT); if (inet_aton( "127.0.0.1" , &client.serverAddr.sin_addr) == 0) { perror ( "Invalid server address" ); exit (EXIT_FAILURE); } // Create a thread to receive messages pthread_create(&receiveThread, NULL, receiveMessages, NULL); // Send and receive messages while (1) { // Get user input printf ( "Enter message: " ); fgets (message, sizeof (message), stdin); // Send message to server sendto(client.socket, message, strlen (message), 0, ( struct sockaddr*)&client.serverAddr, sizeof (client.serverAddr)); } close(client.socket); return 0; } |
- Socket Creation: A UDP socket is created using the socket system call.
- Server Address Configuration: The server address is configured with the server’s IP, port, and protocol details.
- Thread Creation: A thread (receiveThread) is created to run the receiveMessages function concurrently.
- Message Sending Loop: Inside an infinite loop, the client continuously prompts the user for input, sends the message to the server using sendto, and then repeats the process.
- Socket Closure: When the program terminates, the client socket is closed using close.
Step 4: Receive Thread Function
C
void *receiveMessages( void *arg) { char buffer[MAX_MESSAGE_SIZE]; ssize_t bytesRead; while (1) { bytesRead = recvfrom(client.socket, buffer, sizeof (buffer), 0, NULL, NULL); if (bytesRead == -1) { perror ( "Receive failed" ); exit (EXIT_FAILURE); } buffer[bytesRead] = '\0' ; printf ( "Server: %s" , buffer); } } |
- Thread Function Definition: The receiveMessages function continuously receives messages from the server using recvfrom.
- Buffer Initialization: A buffer (buffer) is used to store the received message.
- Error Handling: If the reception fails, an error message is printed, and the program exits with an error status.
- Message Printing: The received message is printed to the console with a prefix indicating it’s from the server.
Step 5: Write the Entire Code
Now, write the entire code in the client.c which is stated below in the code block.
C
#include <arpa/inet.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define PORT 8888 #define MAX_MESSAGE_SIZE 1024 typedef struct { struct sockaddr_in serverAddr; int socket; } Client; Client client; void * receiveMessages( void * arg) { char buffer[MAX_MESSAGE_SIZE]; ssize_t bytesRead; while (1) { bytesRead = recvfrom(client.socket, buffer, sizeof (buffer), 0, NULL, NULL); if (bytesRead == -1) { perror ( "Receive failed" ); exit (EXIT_FAILURE); } buffer[bytesRead] = '\0' ; printf ( "Server: %s" , buffer); } } int main() { pthread_t receiveThread; char message[MAX_MESSAGE_SIZE]; ssize_t bytesRead; // Create socket if ((client.socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror ( "Socket creation failed" ); exit (EXIT_FAILURE); } // Configure server address memset (&client.serverAddr, 0, sizeof (client.serverAddr)); client.serverAddr.sin_family = AF_INET; client.serverAddr.sin_port = htons(PORT); if (inet_aton( "127.0.0.1" , &client.serverAddr.sin_addr) == 0) { perror ( "Invalid server address" ); exit (EXIT_FAILURE); } // Create a thread to receive messages pthread_create(&receiveThread, NULL, receiveMessages, NULL); // Send and receive messages while (1) { // Get user input printf ( "Enter message: " ); fgets (message, sizeof (message), stdin); // Send message to server sendto(client.socket, message, strlen (message), 0, ( struct sockaddr*)&client.serverAddr, sizeof (client.serverAddr)); } close(client.socket); return 0; } |
How to create a multi-chat server using UDP?
In this article, we will see the development of a Multi-Threaded UDP Chat Server-Client Network for Data Transfer in Linux. UDP is used for low latency and connectionless characteristics, the architecture consists of a server managing multiple clients through threading. This networked chat application facilitates real-time communication, allowing users to exchange messages seamlessly. We will create the Server and Client script and perform live execution of communication between the server and multiple clients.