Skip to main content

Concurrent Time Server application using UDP

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(&current_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

  1. Compile the server and client programs separately:
    gcc -o server server.c
    gcc -o client client.c
  2. Run the server program on the remote server:
    ./server
  3. Run the client program on the same or another machine:
    ./client

Expected Output

  • Server:

    Server is running and waiting for time requests on port 12345...
    Received request from client: 127.0.0.1 Sent time to client: Thu Jan 10 14:25:30 2025
  • Client:

    Time request sent to server.
    Current time from server: Thu Jan 10 14:25:30 2025

Server Code Breakdown

Imports and Definitions

#include <stdio.h> // Standard I/O operations
#include <stdlib.h> // Standard library functions (exit, malloc, etc.) #include <string.h> // String manipulation functions #include <time.h> // For fetching system time #include <unistd.h> // For close() function #include <arpa/inet.h> // For socket programming (struct sockaddr_in, etc.)
  • Purpose: Includes the necessary libraries for socket communication, time manipulation, and basic system operations.

Constants

#define PORT 12345 // The server listens on this port
#define BUFFER_SIZE 1024 // Buffer size for communication
  • 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

int sockfd;
struct sockaddr_in server_addr, client_addr; socklen_t addr_len = sizeof(client_addr); char buffer[BUFFER_SIZE]; // Create socket if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("Socket creation failed"); exit(EXIT_FAILURE); }
  • socket(AF_INET, SOCK_DGRAM, 0): Creates a UDP socket.
  • Error Handling: If socket creation fails, the program exits.

Server Address Configuration

memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET; // IPv4 server_addr.sin_addr.s_addr = INADDR_ANY; // Accept connections from any address server_addr.sin_port = htons(PORT); // Convert port to network byte order
  • 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

if (bind(sockfd, (const struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Bind failed"); close(sockfd); exit(EXIT_FAILURE); }
  • bind: Associates the socket with the specified address and port.
  • Error Handling: Exits if the binding fails.

Listening for Requests

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));
  • 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

// Get the current time
time_t current_time = time(NULL); char *time_str = ctime(&current_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); }
  • 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

close(sockfd);
  • Ensures the socket is closed when the server is terminated.

Client Code Breakdown

Imports and Definitions

#include <stdio.h>
#include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #define PORT 12345 #define BUFFER_SIZE 1024
  • Includes libraries similar to the server code.
  • Defines constants for port number and buffer size.

Socket Creation

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); }
  • socket(AF_INET, SOCK_DGRAM, 0): Creates a UDP socket.
  • Error Handling: Exits if socket creation fails.

Server Address Configuration

memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET; // IPv4 server_addr.sin_port = htons(PORT); // Convert port to network byte order server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Replace with server's IP if remote
  • inet_addr("127.0.0.1"): Converts the server's IP address to binary format.

Send Time Request

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");
  • sendto: Sends a message to the server requesting the time.

Receive Server Response

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);
  • recvfrom: Waits for a response from the server.
  • Null-Termination: Ensures the received string is properly terminated before printing.

Close the Socket

close(sockfd);
  • Ensures the socket is closed when the program ends.

Comments

Popular posts from this blog

CSL 332 Networking Lab KTU 2019 Scheme - Dr Binu V P

CSL 332 Networking Lab KTU BTech 2019 Scheme About Me Scheme Syllabus Experiments 1.Learn the Networking Commands and Network Configuration Files     Basic networking commands     More Networking commands     Network configuration Files     View the configuration and address of your network interface     Network Connectivity      View Active TCP connections     MAC address of another machine using ARP  2.  System calls in Network Programming 3.  Simple TCP/IP Client Server Program 4.  Simple UDP Client Server Program 5.Application Programs     Concurrent UDP Time Server     Checking Prime Numbers 6. Simulate ARQ Protocols  / sliding window protocols          Stop and Wait           Go-Back-N          Selective Repeat  7. Routing Protocols - Distance Vector and Link State   ...

Stop and Wait ARQ

Here's a simple C program that demonstrates the Stop-and-Wait ARQ protocol. This basic implementation simulates the sender transmitting packets one at a time and waiting for an acknowledgment from the receiver. If the acknowledgment is not received, the sender retransmits the packet. Key Points: The sender sends one packet at a time. If the receiver acknowledges it (ACK), the sender sends the next packet. If the acknowledgment is lost, the sender retransmits after a timeout. C Program: Stop-and-Wait ARQ Simulation #include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h>  // for sleep() #define TIMEOUT 3  // Timeout duration in seconds #define TOTAL_PACKETS 5  // Number of packets to send int simulate_acknowledgment() {     // Simulate a 70% chance of successful acknowledgment     return rand() % 10 < 7; } int main() {     srand(time(0));  // Seed for random number generation     i...

Server/Client Communication-python

The basic mechanisms of client-server setup are: A client app send a request to a server app.  The server app returns a reply.  Some of the basic data communications between client and server are: File transfer - sends name and gets a file.  Web page - sends url and gets a page.  Echo - sends a message and gets it back.  Client server communication uses socket.              To connect to another machine, we need a socket connection. What's a connection?  A relationship between two machines, where two pieces of software know about each other. Those two pieces of software know how to communicate with each other. In other words, they know how to send bits to each other. A socket connection means the two machines have information about each other, including network location (IP address) and TCP port. (If we can use anology, IP address is the phone number and the TCP port is the extension).  A so...