Skip to main content

File Transfer Protocol (FTP)

FTP Protocol Overview

The File Transfer Protocol (FTP) is a standard network protocol used to transfer files from one host to another over a TCP-based network, such as the Internet. It operates using a client-server architecture. The client requests files or uploads them, while the server responds to these requests. FTP typically uses two channels:

  1. Control Connection: To send commands and receive responses.
  2. Data Connection: To transfer the actual file data.

Simulation of a Simple File Transfer in C using Sockets

Below is an example of a simple simulation of a file transfer protocol where:

  1. The client requests a file by its name.
  2. The server checks if the file exists and sends its content back to the client.

Server Code

The server listens for incoming connections, receives a file request, reads the file, and sends its content to the client

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

#define PORT 8080
#define BUFFER_SIZE 1024

void handle_client(int client_socket) {
char buffer[BUFFER_SIZE] = {0};
char filename[BUFFER_SIZE] = {0};

// Receive filename from client

int bytes_received = recv(client_socket, filename, BUFFER_SIZE, 0);
if (bytes_received < 0) {
perror("Error receiving filename");
close(client_socket);
return;
}

// Open the requested file

FILE *file = fopen(filename, "r");
if (file == NULL) {
char *error_message = "File not found";
send(client_socket, error_message, strlen(error_message), 0);
perror("File not found");
} else {

// Read file and send its content

while (fgets(buffer, BUFFER_SIZE, file) != NULL) {
send(client_socket, buffer, strlen(buffer), 0);
memset(buffer, 0, BUFFER_SIZE);
}

printf("File Send to client\n");
fclose(file);
}
close(client_socket);
}

int main() {

int server_socket, client_socket;
struct sockaddr_in server_addr, client_addr;
socklen_t addr_len = sizeof(client_addr);

// Create server socket

server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == 0) {
perror("Socket failed");
exit(EXIT_FAILURE);
}

// Configure server address
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);

// Bind socket to address
if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Bind failed");
exit(EXIT_FAILURE);
}

// Start listening
if (listen(server_socket, 3) < 0) {
perror("Listen failed");
exit(EXIT_FAILURE);
}

printf("Server is listening on port %d\n", PORT);
while (1) {
// Accept client connection
client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &addr_len);
if (client_socket < 0) {
perror("Accept failed");
exit(EXIT_FAILURE);
}

printf("Client connected\n");
// Handle client

handle_client(client_socket);
}

close(server_socket);
return 0;
}

Client Code

The client connects to the server, sends the file name, and displays the received file content.

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

#define PORT 8080
#define BUFFER_SIZE 1024

int main() {
int client_socket;
struct sockaddr_in server_addr;
char buffer[BUFFER_SIZE] = {0};
char filename[BUFFER_SIZE] = {0};

// Create client socket

client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket < 0) {
    perror("Socket creation failed");
    exit(EXIT_FAILURE);
    }

// 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");

// Connect to server
if (connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection failed");
exit(EXIT_FAILURE);

}
// Get filename from user
printf("Enter the filename to request: ");
scanf("%s", filename);

// Send filename to server
send(client_socket, filename, strlen(filename), 0);

// Receive and print file content

printf("File content received:\n");
while (recv(client_socket, buffer, BUFFER_SIZE, 0) > 0) {
printf("%s", buffer);
memset(buffer, 0, BUFFER_SIZE);
}

printf("\n");
close(client_socket);

return 0;
}

How to Run

  1. Save the server code in a file, e.g., server.c, and compile it:


    gcc server.c -o server
  2. Save the client code in a file, e.g., client.c, and compile it:


    gcc client.c -o client
  3. Run the server in one terminal:


    ./server
  4. Run the client in another terminal:


    ./client
  5. Enter the name of a file available in the server's directory. If the file exists, the client will receive and display its content.

This simulation demonstrates the basic principles of an FTP-like file transfer. For real-world FTP implementations, authentication, error handling, and additional features are required.

Code Explanation

Server Code

The server is designed to:

  1. Listen for client connections.
  2. Receive a file request from the client.
  3. Send the file's content back to the client if it exists.

  1. Include Headers:


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

    These headers provide necessary functions for I/O operations, socket programming, and memory handling.

  2. Constants:


    #define PORT 8080 #define BUFFER_SIZE 1024
    • PORT: The server listens on port 8080. This can be changed as needed.
    • BUFFER_SIZE: Sets the size of the buffer for file reading and sending data.
  3. handle_client Function:
    This function processes each client request.


    void handle_client(int client_socket) { char buffer[BUFFER_SIZE] = {0}; char filename[BUFFER_SIZE] = {0};
    • filename: Stores the name of the requested file.

    • buffer: Temporary storage for reading file content.

    • Receive Filename:


      int bytes_received = recv(client_socket, filename, BUFFER_SIZE, 0);

      recv receives the filename from the client. If bytes_received is negative, an error occurred.

    • Check and Open the File:


      FILE *file = fopen(filename, "r"); if (file == NULL) { char *error_message = "File not found"; send(client_socket, error_message, strlen(error_message), 0); perror("File not found"); }

      If the file doesn't exist, an error message is sent back to the client.

    • Read and Send File Content:


      while (fgets(buffer, BUFFER_SIZE, file) != NULL) { send(client_socket, buffer, strlen(buffer), 0); memset(buffer, 0, BUFFER_SIZE); } fclose(file);
      • fgets reads a line from the file.
      • send sends the content line-by-line to the client.
      • memset clears the buffer after each send.
    • Close Connection:


      close(client_socket);
  4. Main Function:

    • Create Socket:


      server_socket = socket(AF_INET, SOCK_STREAM, 0);

      Creates a TCP socket.

    • Bind Socket to Address:


      bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));

      Binds the socket to PORT and INADDR_ANY (all available interfaces).

    • Start Listening:


      listen(server_socket, 3);

      Listens for incoming connections. The 3 specifies the maximum queue length for pending connections.

    • Accept Connections in a Loop:

      ]
      client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &addr_len); handle_client(client_socket);
      • accept waits for a client to connect.
      • handle_client is called to process the client request.

Client Code

The client is designed to:

  1. Connect to the server.
  2. Send the name of the requested file.
  3. Receive and display the file content.

  1. Include Headers:
    Similar to the server code.

  2. Constants:
    Same as the server code.

  3. Main Function:

    • Create Socket:


      client_socket = socket(AF_INET, SOCK_STREAM, 0);

      Creates a TCP socket.

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

      Specifies the server's IP (127.0.0.1 for localhost) and port.

    • Connect to Server:


      connect(client_socket, (struct sockaddr *)&server_addr, sizeof(server_addr));

      Initiates a connection to the server.

    • Send Filename:


      send(client_socket, filename, strlen(filename), 0);

      Sends the name of the requested file to the server.

    • Receive and Print File Content:


      while (recv(client_socket, buffer, BUFFER_SIZE, 0) > 0) { printf("%s", buffer); memset(buffer, 0, BUFFER_SIZE); }
      • recv receives file content from the server.
      • printf displays the received content.
    • Close Socket:


      close(client_socket);

Key Points:

  1. Error Handling:

    • Server handles cases where the file is not found.
    • Proper error messages are displayed on both server and client.
  2. Buffered Transfer:
    Data is read and sent in chunks (BUFFER_SIZE).

  3. Client-Server Communication:

    • Client sends a filename.
    • Server responds with either the file content or an error message.
  4. Multithreading (Optional):
    The server can be extended to handle multiple clients using threads or fork.

This simple simulation demonstrates the basic workflow of file transfer using sockets in C.

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...