├── .gitignore ├── Data ├── Client │ └── client_text.txt └── Server │ └── server_text.txt ├── README.md ├── include ├── client.h ├── logging.h └── server.h └── src ├── client.cpp └── server.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Custom ignores. 35 | # Build directories. 36 | build/ 37 | .build/ 38 | # Temp directories. 39 | temp/ 40 | .temp/ 41 | -------------------------------------------------------------------------------- /Data/Client/client_text.txt: -------------------------------------------------------------------------------- 1 | 1.This is Test File. 2 | 2. 3 | 3.Format : Text 4 | 4.Size : Less than 100 Bytes 5 | 5.------------------------------------------- 6 | 6.Destination : Server "Data/server_tses.txt" 7 | 7.Source : Client "Data/client_test.txt" 8 | 8. 9 | 9.End of File -------------------------------------------------------------------------------- /Data/Server/server_text.txt: -------------------------------------------------------------------------------- 1 | 1.This is Test File. 2 | 2. 3 | 3.Format : Text 4 | 4.Size : Less than 100 Bytes 5 | 5.------------------------------------------- 6 | 6.Destination : Server "Data/server_tses.txt" 7 | 7.Source : Client "Data/client_test.txt" 8 | 8. 9 | 9.End of File -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TCP-File-Transfer 2 | C++ programs to transfer a Text file from server to client using TCP 3 | 4 | ## Basic Instructions 5 | The CPP files were compiled and ran on Ubuntu [WSL]. 6 | 7 | Direction of file Transfer: Server to Client. 8 | The path of text file to send can be changed in the `file_server.cpp` on line 37. 9 | 10 | **NOTE**: The char array `buffer` in `file_client.cpp` is default to 1KB, you may need to increase the file size as per the larger file's size. 11 | 12 | ## References for function used in the code... 13 | - Socket Programming basics : https://www.geeksforgeeks.org/socket-programming-cc/ 14 | 15 | ### Socket Program basics 16 | - `inet_pton()` : http://man7.org/linux/man-pages/man3/inet_pton.3.html 17 | 18 | - `sockaddr_in` and `in_addr` : https://www.gta.ufrj.br/ensino/eel878/sockets/sockaddr_inman.html 19 | - `socket()` : http://man7.org/linux/man-pages/man2/socket.2.html 20 | - `bind()` : http://man7.org/linux/man-pages/man2/bind.2.html 21 | - `listen()` : http://man7.org/linux/man-pages/man2/listen.2.html 22 | - `accept()` : http://man7.org/linux/man-pages/man2/accept.2.html 23 | 24 | - `read()` : http://man7.org/linux/man-pages/man2/read.2.html 25 | - `send()` : http://man7.org/linux/man-pages/man2/send.2.html 26 | 27 | ### File handling 28 | - Copying whole text to string buffer before transmission 29 | https://stackoverflow.com/questions/18398167/how-to-copy-a-txt-file-to-a-char-array-in-c 30 | 31 | 32 | Good luck! 33 | -------------------------------------------------------------------------------- /include/client.h: -------------------------------------------------------------------------------- 1 | #ifndef CLIENT_H 2 | #define CLIENT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | class Client{ 15 | int PORT; 16 | int general_socket_descriptor; 17 | struct sockaddr_in address; 18 | int address_length; 19 | std::fstream file; 20 | 21 | public: 22 | Client(); 23 | void create_socket(); 24 | void create_connection(); 25 | void receive_file(); 26 | }; 27 | 28 | #endif // CLIENT_H -------------------------------------------------------------------------------- /include/logging.h: -------------------------------------------------------------------------------- 1 | #ifndef LOGGING_H 2 | #define LOGGING_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class Logger { 12 | public: 13 | enum LogLevel { DEBUG, INFO, WARNING, ERROR }; 14 | 15 | Logger() {}; 16 | 17 | template 18 | void debug(const std::string_view formatString, Args&&... args) { 19 | log(Logger::DEBUG, formatString, args...); 20 | } 21 | 22 | template 23 | void info(const std::string_view formatString, Args&&... args) { 24 | log(Logger::INFO, formatString, args...); 25 | } 26 | 27 | template 28 | void warning(const std::string_view formatString, Args&&... args) { 29 | log(Logger::WARNING, formatString, args...); 30 | } 31 | 32 | template 33 | void error(const std::string_view formatString, Args&&... args) { 34 | log(Logger::ERROR, formatString, args...); 35 | } 36 | 37 | private: 38 | template 39 | void log(Logger::LogLevel level, const std::string_view formatString, 40 | Args&&... args) { 41 | std::map logLevelMap = {{DEBUG, "DEBUG"}, 42 | {INFO, "INFO"}, 43 | {WARNING, "WARNING"}, 44 | {ERROR, "ERROR"}}; 45 | 46 | std::string logLevelTag = logLevelMap[level]; 47 | 48 | std::cout << "[" << logLevelTag << "]: " 49 | << std::vformat(formatString, std::make_format_args(args...)) 50 | << std::endl; 51 | } 52 | }; 53 | 54 | #endif // LOGGING_H 55 | -------------------------------------------------------------------------------- /include/server.h: -------------------------------------------------------------------------------- 1 | #ifndef SERVER_H 2 | #define SERVER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | class Server{ 15 | int PORT; 16 | int general_socket_descriptor; 17 | struct sockaddr_in address; 18 | int new_socket_descriptor; 19 | int address_length; 20 | std::fstream file; 21 | 22 | public: 23 | Server(); 24 | void create_socket(); 25 | void bind_socket(); 26 | void set_listen_set(); 27 | void accept_connection(); 28 | void transmit_file(); 29 | }; 30 | 31 | #endif // SERVER_H -------------------------------------------------------------------------------- /src/client.cpp: -------------------------------------------------------------------------------- 1 | #include "client.h" 2 | #include "logging.h" 3 | 4 | using namespace std; 5 | 6 | Client::Client(){ 7 | Logger logger; 8 | 9 | create_socket(); 10 | PORT = 8050; 11 | logger.debug("PORT: ", PORT); 12 | 13 | address.sin_family = AF_INET; 14 | address.sin_port = htons( PORT ); 15 | address_length = sizeof(address); 16 | if(inet_pton(AF_INET, "127.0.0.1", &address.sin_addr)<=0) { 17 | logger.error("Invalid address"); 18 | } 19 | 20 | create_connection(); 21 | 22 | file.open("client_text.txt", ios::out | ios::trunc | ios::binary); 23 | if(file.is_open()){ 24 | logger.info("File downloaded."); 25 | } 26 | else{ 27 | logger.error("File creation failed, Exititng."); 28 | exit(-1); 29 | } 30 | } 31 | 32 | void Client::create_socket(){ 33 | Logger logger; 34 | 35 | if ((general_socket_descriptor = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 36 | perror("[ERROR] : Socket failed.\n"); 37 | exit(EXIT_FAILURE); 38 | } 39 | logger.info("Socket Created Successfully."); 40 | } 41 | 42 | void Client::create_connection(){ 43 | Logger logger; 44 | 45 | if (connect(general_socket_descriptor, (struct sockaddr *)&address, sizeof(address)) < 0) { 46 | perror("[ERROR] : connection attempt failed.\n"); 47 | exit(EXIT_FAILURE); 48 | } 49 | logger.info("Connection Successfull."); 50 | } 51 | 52 | void Client::receive_file(){ 53 | Logger logger; 54 | 55 | char buffer[1024] = {}; 56 | int valread = read(general_socket_descriptor , buffer, 1024); 57 | logger.info("Data received {} bytes.", valread); 58 | logger.info("Saving data to file."); 59 | 60 | file<(file)), std::istreambuf_iterator()); 72 | logger.info("Transmission Data Size {} Bytes.", contents.length()); 73 | logger.info("Sending file..."); 74 | 75 | int bytes_sent = send(new_socket_descriptor , contents.c_str() , contents.length() , 0 ); 76 | logger.info("Transmitted Data Size {} Bytes.", bytes_sent); 77 | logger.info("File Transfer Complete."); 78 | } 79 | 80 | 81 | int main(){ 82 | Server S; 83 | S.transmit_file(); 84 | return 0; 85 | } 86 | --------------------------------------------------------------------------------