This repository contains a data transfer system implemented through a server and client application. The project is designed to efficiently transfer files from the server to the client, enabling seamless data communication between the two components. The system is specifically designed for reliable data transmission, ensuring that files are sent and received accurately and efficiently.
The server application is responsible for handling client connections and efficiently transferring files to connected clients. Upon execution, the server initializes a socket and binds it to the default IP address of the system. It then listens for incoming client connections on the specified port.
The server is designed to handle multiple client connections concurrently. It uses a thread pool, allowing it to create a fixed number of worker threads. These worker threads wait for file tasks to be pushed into the server's queue. When a client connects and requests a file transfer, the server creates a communication thread for that client. The communication thread is responsible for reading the client's requested directory and other essential metadata.
As the communication thread reads the client's request, it pushes new file tasks into the server's queue. The worker threads in the thread pool then process these tasks and send the requested files to the respective clients.
The client application connects to the server using the specified IP address and port number. Upon successful connection, the client reads essential metadata from the server, including the block size for data transfer and the total number of files to expect.
For each file received from the server, the client reads the metadata, which includes the total number of bytes for the file and the file's name. The client then creates the specified directory (extracted from the filename) if it does not already exist. If the file already exists, the client deletes it and recreates it.
The client then reads the data from the server in blocks of the specified block size. It writes the received data to the corresponding file. This process continues until all files are received from the server.
To compile the entire project (both Server and Client), execute the following command in root project directory:
make allTo compile only the Server, navigate to the ./server/ directory and run:
make serverTo compile only the Client, navigate to the ./client/ directory and run:
make clientTo execute the Server with default arguments, go to the ./server/ directory and run:
make runServerAlternatively, you can customize the Server's execution by specifying the following arguments:
./dataServer -p <port> -s <thread_pool_size> -q <queue_size> -b <block_size><port>: The port number on which the Server will listen for incoming client connections.<thread_pool_size>: The number of threads in the Server's thread pool, determining the maximum number of clients that can be served concurrently.<queue_size>: The maximum number of file tasks that can be held in the server's queue before the worker threads start processing them.<block_size>: The size of data blocks that are transferred between the Server and Client.
To run the Client with default arguments, go to the ./client/ directory and use the following command:
make runClientYou can also customize the Client's execution by providing the following arguments:
./remoteClient -i <server_ip> -p <server_port> -d <directory><server_ip>: The IP address of the Server to which the Client will connect.<server_port>: The port number on which the Server is listening for incoming connections.<directory>: The directory path (relative to the server's side) from which the Client requests files to be transferred.
The files and directories received from the Server will be copied into the ./client/ directory.