Implementation of a Concurrent File Server Using UDP Socket Programming

 

Implementation of a Concurrent File Server Using UDP Socket Programming


Aim

To implement a concurrent file server using UDP socket programming in C, where multiple clients can request files simultaneously. The server sends the contents of the requested file if it exists; otherwise, it sends an appropriate error message. The server also sends its Process ID (PID) along with the response.


Objectives

After completing this experiment, students should be able to:

  1. Understand UDP socket programming.
  2. Learn connectionless communication.
  3. Understand concurrent server implementation using fork().
  4. Learn file handling in C.
  5. Transfer files using UDP sockets.
  6. Understand Process IDs (PID).
  7. Handle file-not-found conditions.

Theory

File Server

A File Server is a network application that stores files and supplies them to clients on request.

Whenever a client requests a file,

  • the server searches for the file,
  • if found, sends the file contents,
  • otherwise sends an error message.

File servers are widely used in

  • Cloud Storage
  • FTP Servers
  • Web Servers
  • Database Servers
  • Network Storage Systems

UDP Socket Programming

UDP (User Datagram Protocol) is a connectionless transport layer protocol.

Unlike TCP,

  • no connection establishment is required,
  • communication occurs through datagrams,
  • lower overhead,
  • faster communication.

UDP provides

  • low latency
  • faster communication
  • simple implementation

However,

  • packet delivery is not guaranteed,
  • packet ordering is not guaranteed,
  • no retransmission mechanism exists.

Hence UDP is suitable for lightweight request-response applications.


Concurrent UDP Server

Unlike TCP, UDP does not establish separate client connections.

Whenever a datagram arrives,

the server

  • receives the request,
  • creates a child process using fork(),
  • the child serves that client,
  • the parent immediately waits for the next request.

Thus several clients can be served simultaneously.


Process ID (PID)

Every Linux process has a unique Process ID.

The PID is obtained using

getpid();

The child process handling the client's request sends its PID along with the response.

Example

Handled by Server PID : 4821

File Handling Functions

FunctionPurpose
fopen()    Opens file
fgets()    Reads one line
fclose()    Closes file
sprintf()    Formats output
getpid()    Returns Process ID

Working Principle

                    +-------------------------+
                    |     UDP File Server     |
                    +------------+------------+
                                 |
                        Receives File Request
                                 |
                              fork()
                   +-------------+--------------+
                   |                            |
              Parent Process             Child Process
          Waits for new requests        Opens requested file
                                               |
                                   File Exists ?
                                       /     \
                                     Yes      No
                                     |         |
                          Read File Contents   Error Message
                                     |         |
                          Attach Process ID (PID)
                                     |
                              sendto() Client

Functions Used

FunctionPurpose
socket()    Creates UDP socket
bind()    Associates socket with port
recvfrom()    Receives filename
sendto()    Sends response
fork()    Creates child process
fopen()    Opens file
fgets()    Reads file
fclose()    Closes file
getpid()    Returns PID
close()    Closes socket

Algorithm

Server Algorithm

  1. Create a UDP socket.
  2. Bind the socket to port 9000.
  3. Wait for a filename from the client.
  4. Receive the filename.
  5. Create a child process using fork().
  6. Child process:
    • Obtain its PID.
    • Open the requested file.
    • If the file exists:
      • Read its contents.
      • Attach the PID.
      • Send the response to the client.
    • Otherwise:
      • Send the PID.
      • Send "File Not Found".
    • Exit.
  7. Parent waits for the next client request.

Client Algorithm

  1. Create UDP socket.
  2. Enter filename.
  3. Send filename to server.
  4. Receive server response.
  5. Display PID.
  6. Display file contents.
  7. Close socket.

Program

UDP Server Program (server.c)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>

#define PORT 9000
#define BUFFER_SIZE 2048

int main()
{
    int sockfd;

    struct sockaddr_in server,client;

    socklen_t len=sizeof(client);

    char filename[100];

    char buffer[BUFFER_SIZE];

    sockfd=socket(AF_INET,SOCK_DGRAM,0);

    server.sin_family=AF_INET;
    server.sin_addr.s_addr=INADDR_ANY;
    server.sin_port=htons(PORT);

    bind(sockfd,(struct sockaddr *)&server,sizeof(server));

    printf("====================================\n");
    printf(" UDP Concurrent File Server Started\n");
    printf(" Listening on Port %d\n",PORT);
    printf("====================================\n");

    while(1)
    {
        memset(filename,0,sizeof(filename));

        recvfrom(sockfd,
                 filename,
                 sizeof(filename),
                 0,
                 (struct sockaddr *)&client,
                 &len);

        if(fork()==0)
        {
            FILE *fp;

            fp=fopen(filename,"r");

            memset(buffer,0,sizeof(buffer));

            sprintf(buffer,
                    "Handled by Server PID : %d\n\n",
                    getpid());

            if(fp==NULL)
            {
                strcat(buffer,
                       "Requested File Not Found.\n");
            }
            else
            {
                char line[256];

                while(fgets(line,sizeof(line),fp)!=NULL)
                {
                    strcat(buffer,line);
                }

                fclose(fp);
            }

            sendto(sockfd,
                   buffer,
                   strlen(buffer)+1,
                   0,
                   (struct sockaddr *)&client,
                   len);

            printf("Request for %s served by PID %d\n",
                    filename,
                    getpid());

            exit(0);
        }
    }

    close(sockfd);

    return 0;
}


Client Program (client.c)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>

#define PORT 9000
#define BUFFER_SIZE 2048

int main()
{
    int sockfd;

    struct sockaddr_in server;

    socklen_t len=sizeof(server);

    char filename[100];

    char buffer[BUFFER_SIZE];

    /* Create UDP Socket */

    sockfd=socket(AF_INET,SOCK_DGRAM,0);

    if(sockfd<0)
    {
        printf("Socket Creation Failed\n");
        return 0;
    }

    /* Server Information */

    server.sin_family=AF_INET;
    server.sin_port=htons(PORT);
    server.sin_addr.s_addr=inet_addr("127.0.0.1");

    /* Get File Name */

    printf("Enter File Name : ");

    scanf("%s",filename);

    /* Send File Name to Server */

    sendto(sockfd,
           filename,
           strlen(filename)+1,
           0,
           (struct sockaddr *)&server,
           len);

    /* Receive Response */

    recvfrom(sockfd,
             buffer,
             sizeof(buffer),
             0,
             NULL,
             NULL);

    /* Display Response */

    printf("\n=====================================\n");
    printf("Response Received From Server\n");
    printf("=====================================\n\n");

    printf("%s\n",buffer);

    close(sockfd);

    return 0;
}

Compilation

Open a terminal and compile both programs.

gcc server.c -o server

gcc client.c -o client

Preparing Sample Files

Create a few text files in the same directory as the server program.

sample1.txt

Government Model Engineering College

Department of Computer Engineering

Computer Networks Laboratory

sample2.txt

UDP Socket Programming

Concurrent File Server

Linux Programming

notes.txt

Welcome to the Computer Networks Lab.

This experiment demonstrates a concurrent
UDP File Server using fork().

Each client request is handled by a
separate child process.

Execution Procedure

Step 1

Open Terminal 1.

Run the server.

./server

Step 2

Open Terminal 2.

Run the first client.

./client

Step 3

Enter

sample1.txt

Step 4

Open another terminal.

Run another client.

./client

Enter

sample2.txt

Step 5

Open another terminal.

Run another client.

./client

Enter

abc.txt

where abc.txt does not exist.


Sample Output

Server Terminal

====================================
 UDP Concurrent File Server Started
 Listening on Port 9000
====================================

Request for sample1.txt served by PID 4213

Request for sample2.txt served by PID 4216

Request for abc.txt served by PID 4219

Observe that every client is served by a different child process, identified by a unique Process ID (PID).


Client 1

Enter File Name :

sample1.txt

=====================================
Response Received From Server
=====================================

Handled by Server PID : 4213

Government Model Engineering College

Department of Computer Engineering

Computer Networks Laboratory

Client 2

Enter File Name :

sample2.txt

=====================================
Response Received From Server
=====================================

Handled by Server PID : 4216

UDP Socket Programming

Concurrent File Server

Linux Programming

Client 3

Enter File Name :

abc.txt

=====================================
Response Received From Server
=====================================

Handled by Server PID : 4219

Requested File Not Found.

Program Explanation

Server Program

Step 1

Creates a UDP socket using

socket(AF_INET, SOCK_DGRAM, 0);

Step 2

Binds the socket to Port 9000.

bind(sockfd,
    (struct sockaddr *)&server,
    sizeof(server));

Step 3

Waits for a filename from any client.

recvfrom(...)

Step 4

When a filename arrives, the server creates a child process using

fork();

The parent immediately returns to waiting for the next request.

The child serves the current client.


Step 5

The child opens the requested file.

fopen(filename,"r");

Step 6

If the file exists,

the child

  • reads each line using fgets(),
  • appends it to the output buffer.

Step 7

The child obtains its Process ID.

getpid();

Step 8

The PID is added to the beginning of the response.

Example

Handled by Server PID : 4213

Step 9

The completed response is sent back using

sendto()

Step 10

The child process terminates.

exit(0);

Client Program

Step 1

Creates a UDP socket.


Step 2

Accepts a filename from the user.

Example

sample1.txt

Step 3

Sends the filename to the server.

sendto()

Step 4

Waits for the server's response.

recvfrom()

Step 5

Displays

  • Server PID
  • File contents
  • Error message (if the file is not found)

Applications

Concurrent file servers are widely used in computer networks and distributed systems. Some important applications include:

  1. File Sharing Systems
  2. Cloud Storage Services
  3. FTP Servers
  4. Web Servers
  5. Distributed Computing Systems
  6. Network Attached Storage (NAS)
  7. Database Backup Servers
  8. Software Distribution Servers
  9. Remote Document Sharing
  10. Embedded and IoT File Services

Advantages

  1. Uses UDP, resulting in lower communication overhead.
  2. Faster communication due to the absence of connection establishment.
  3. Supports multiple client requests.
  4. Each client request is handled by a separate child process.
  5. Easy to understand and implement.
  6. Demonstrates process creation using fork().
  7. Introduces Process ID (PID) handling.
  8. Provides practical experience in network file transfer.
  9. Simple client-server architecture.
  10. Suitable for undergraduate networking laboratories.

Limitations

  1. UDP does not guarantee reliable delivery.
  2. Packets may be lost during transmission.
  3. Packet ordering is not guaranteed.
  4. Large files may require fragmentation.
  5. No retransmission mechanism is provided.
  6. Suitable only for transferring small text files.
  7. No client authentication is implemented.
  8. No encryption or security mechanisms are provided.

Precautions

  1. Ensure that the server is started before executing the client.
  2. Store all sample text files in the same directory as the server program.
  3. Verify that the requested filename is entered correctly.
  4. Ensure that port 9000 is not being used by another application.
  5. Use only small text files for this experiment.
  6. Compile both programs successfully before execution.
  7. Ensure the client specifies the correct server IP address.
  8. Close all terminals properly after completing the experiment.

Result

A concurrent File Server application was successfully implemented using UDP socket programming. The server received filename requests from clients, created a child process using the fork() system call to handle each request, and returned either the requested file contents or an appropriate error message along with the child process's Process ID (PID). The experiment demonstrated connectionless communication using UDP, concurrent request handling through process creation, and file transfer over a network.

Comments

Popular posts from this blog

Networks Lab PCCSL507 Semester 5 KTU CS 2024 Scheme - Dr Binu V P

Study of whois Command

Study and Use of ifconfig Command