Below is a simple implementation of a Concurrent Time Server application using UDP in C. This program consists of two parts: the server and the client.
Server Code
The server listens for time requests and sends its system time back to the client.
// Server Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 12345
#define BUFFER_SIZE 1024
int main() {
int sockfd;
struct sockaddr_in server_addr, client_addr;
char buffer[BUFFER_SIZE];
socklen_t addr_len = sizeof(client_addr);
// Create socket
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
memset(&server_addr, 0, sizeof(server_addr));
memset(&client_addr, 0, sizeof(client_addr));
// Configure server address
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);
// Bind the socket to the address
if (bind(sockfd, (const struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Bind failed");
close(sockfd);
exit(EXIT_FAILURE);
}
printf("Server is running and waiting for time requests on port %d...\n", PORT);
while (1) {
memset(buffer, 0, BUFFER_SIZE);
// Receive message from client
int n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&client_addr, &addr_len);
if (n < 0) {
perror("Receive failed");
continue;
}
printf("Received request from client: %s\n", inet_ntoa(client_addr.sin_addr));
// Get the current time
time_t current_time = time(NULL);
char *time_str = ctime(¤t_time);
// Send the current time back to the client
sendto(sockfd, time_str, strlen(time_str), 0, (struct sockaddr *)&client_addr, addr_len);
printf("Sent time to client: %s", time_str);
}
close(sockfd);
return 0;
}
Client Code
The client sends a request to the server and displays the received time.
// Client Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 12345
#define BUFFER_SIZE 1024
int main() {
int sockfd;
struct sockaddr_in server_addr;
char buffer[BUFFER_SIZE];
char *request_message = "TIME_REQUEST";
// Create socket
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
memset(&server_addr, 0, sizeof(server_addr));
// Configure server address
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Replace with server IP if needed
// Send time request to server
if (sendto(sockfd, request_message, strlen(request_message), 0,
(const struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Send failed");
close(sockfd);
exit(EXIT_FAILURE);
}
printf("Time request sent to server.\n");
// Receive response from server
int n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, NULL, NULL);
if (n < 0) {
perror("Receive failed");
close(sockfd);
exit(EXIT_FAILURE);
}
buffer[n] = '\0'; // Null-terminate the received string
printf("Current time from server: %s\n", buffer);
close(sockfd);
return 0;
}
How to Run
- Compile the server and client programs separately:
- Run the server program on the remote server:
- Run the client program on the same or another machine:
Expected Output
Server:
Client:
Server Code Breakdown
Imports and Definitions
- Purpose: Includes the necessary libraries for socket communication, time manipulation, and basic system operations.
Constants
- PORT: The port number on which the server will listen for requests.
- BUFFER_SIZE: Defines the maximum size of data the server can send/receive.
Socket Creation
socket(AF_INET, SOCK_DGRAM, 0)
: Creates a UDP socket.- Error Handling: If socket creation fails, the program exits.
Server Address Configuration
INADDR_ANY
: Allows the server to listen on all available network interfaces.htons(PORT)
: Converts the port number to network byte order.
Binding the Socket
bind
: Associates the socket with the specified address and port.- Error Handling: Exits if the binding fails.
Listening for Requests
recvfrom
: Waits for a message from a client.inet_ntoa(client_addr.sin_addr)
: Converts the client’s IP address to a human-readable format.
Send System Time to Client
time(NULL)
: Fetches the current system time.ctime
: Converts the time to a human-readable string.sendto
: Sends the time string to the client.
Closing Resources
- Ensures the socket is closed when the server is terminated.
Client Code Breakdown
Imports and Definitions
- Includes libraries similar to the server code.
- Defines constants for port number and buffer size.
Socket Creation
socket(AF_INET, SOCK_DGRAM, 0)
: Creates a UDP socket.- Error Handling: Exits if socket creation fails.
Server Address Configuration
inet_addr("127.0.0.1")
: Converts the server's IP address to binary format.
Send Time Request
sendto
: Sends a message to the server requesting the time.
Receive Server Response
recvfrom
: Waits for a response from the server.- Null-Termination: Ensures the received string is properly terminated before printing.
Close the Socket
- Ensures the socket is closed when the program ends.
Comments
Post a Comment