Untitled
unknown
plain_text
a month ago
8.3 kB
3
Indexable
#include <iostream> #include <fstream> #include <vector> #include <string> #include <thread> #include <filesystem> #include <cstring> #include <sys/socket.h> #include <arpa/inet.h> #include <unistd.h> #include <ifaddrs.h> #define PORT 4444 #define BUFFER_SIZE 1024 using namespace std; using namespace filesystem; // Function declarations string getIPAddress(); void sendFile(int clientSocket, const string &filename); int receiveFile(int peerSocket, const string &filename); int handleFiles(int clientSocket); vector<string> getFileList(const string &path); int startServer(); int main() { string IPADDRESS = getIPAddress(); vector<string> filesNameList = getFileList("../files"); string serverIP; cout << "Enter server IP: "; cin >> serverIP; // Start a local server thread thread serverThread(startServer); serverThread.detach(); // Create a socket int clientSocket = socket(AF_INET, SOCK_STREAM, 0); if (clientSocket == -1) { cerr << "Failed to create socket.\n"; return -1; } // Configure server address sockaddr_in serverAddr{}; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(PORT); inet_pton(AF_INET, serverIP.c_str(), &serverAddr.sin_addr); // Connect to the server if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) { cerr << "Failed to connect to the server.\n"; close(clientSocket); return -1; } // Send filenames and IP address to the server string fileData; for (const auto &file : filesNameList) { fileData += file + ' ' + IPADDRESS + ':'; } send(clientSocket, fileData.c_str(), fileData.length(), 0); // Handle file requests while (true) { if (handleFiles(clientSocket)) { break; } } // Send exit command and close socket string exitCommand = "exit"; send(clientSocket, exitCommand.c_str(), exitCommand.size(), 0); close(clientSocket); return 0; } void sendFile(int clientSocket, const string &filename) { ifstream file("../files/" + filename, ios::binary); if (!file.is_open()) { cerr << "Error: Could not open file " << filename << "\n"; string errorMsg = "Error: File not found"; send(clientSocket, errorMsg.c_str(), errorMsg.size(), 0); return; } char buffer[BUFFER_SIZE]; while (!file.eof()) { file.read(buffer, BUFFER_SIZE); streamsize bytesRead = file.gcount(); if (bytesRead > 0) { send(clientSocket, buffer, bytesRead, 0); } } file.close(); cout << "File " << filename << " sent successfully.\n"; } int receiveFile(int peerSocket, const string &filename) { ofstream outFile("../files/" + filename, ios::binary); if (!outFile.is_open()) { cerr << "Error: Could not create file " << filename << "\n"; return -1; } char buffer[BUFFER_SIZE]; int bytesRead; struct timeval timeout; timeout.tv_sec = 1; // Set timeout to 1 seconds timeout.tv_usec = 0; // Set the timeout option for the socket setsockopt(peerSocket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout)); while ((bytesRead = recv(peerSocket, buffer, BUFFER_SIZE, 0)) > 0) { outFile.write(buffer, bytesRead); } if (bytesRead < 0) { cerr << "Error: Failed to receive file data.\n"; outFile.close(); return -1; } outFile.close(); cout << "File " << filename << " received successfully.\n"; return 0; } int handleFiles(int clientSocket) { string input; cout << "Enter filenames to request (separated by spaces, or 'exit' to quit): "; getline(cin >> ws, input); if (input == "exit") { return 1; } vector<string> filenames; size_t pos = 0, found; while ((found = input.find(' ', pos)) != string::npos) { filenames.push_back(input.substr(pos, found - pos)); pos = found + 1; } filenames.push_back(input.substr(pos)); for (const auto &filename : filenames) { string command = "Send " + filename; send(clientSocket, command.c_str(), command.size(), 0); char response[BUFFER_SIZE] = {0}; int bytesRead = read(clientSocket, response, BUFFER_SIZE); if (bytesRead <= 0 || string(response).find("File not found") != string::npos) { cerr << "Error: File not found on server: " << filename << "\n"; continue; } int peerSocket = socket(AF_INET, SOCK_STREAM, 0); if (peerSocket == -1) { cerr << "Failed to create server socket.\n"; return -1; } string ip_addr_of_recipient = string(response); sockaddr_in peerServerAddr; memset(&peerServerAddr, 0, sizeof(peerServerAddr)); peerServerAddr.sin_family = AF_INET; peerServerAddr.sin_port = htons(5555); inet_pton(AF_INET, string(response).c_str(), &peerServerAddr.sin_addr); if (connect(peerSocket, (struct sockaddr *)&peerServerAddr, sizeof(peerServerAddr)) == -1) { cout << "Peer socket connection failed" << endl; continue; } command = "Send " + filename; send(peerSocket, command.c_str(), command.size(), 0); receiveFile(peerSocket, filename); } return 0; } vector<string> getFileList(const string &path) { vector<string> fileList; for (const auto &entry : directory_iterator(path)) { fileList.push_back(entry.path().filename().string()); } return fileList; } int startServer() { int serverSocket = socket(AF_INET, SOCK_STREAM, 0); if (serverSocket == -1) { cerr << "Failed to create server socket.\n"; return -1; } sockaddr_in serverAddr{}; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(5555); serverAddr.sin_addr.s_addr = INADDR_ANY; if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1) { cerr << "Failed to bind socket.\n"; close(serverSocket); return -1; } if (listen(serverSocket, 5) == -1) { cerr << "Failed to listen on socket.\n"; close(serverSocket); return -1; } cout << "Server is listening on port " << 5555 << "...\n"; while (true) { sockaddr_in clientAddr{}; socklen_t clientLen = sizeof(clientAddr); int clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr, &clientLen); if (clientSocket == -1) { cerr << "Failed to accept connection.\n"; continue; } char buffer[2048] = {0}; read(clientSocket, buffer, sizeof(buffer)); string response = string(buffer); if (response.rfind("Send ", 0) != string::npos) { sendFile(clientSocket, response.substr(5)); } } } string getIPAddress() { struct ifaddrs *interfaces = nullptr; struct ifaddrs *temp_addr = nullptr; std::string ipAddress = "Unable to get IP Address"; // Retrieve the list of network interfaces if (getifaddrs(&interfaces) == 0) { temp_addr = interfaces; while (temp_addr != nullptr) { if (temp_addr->ifa_addr && temp_addr->ifa_addr->sa_family == AF_INET) { // Check if it's an IPv4 address and not the loopback interface if (strcmp(temp_addr->ifa_name, "lo") != 0) { ipAddress = inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr); break; } } temp_addr = temp_addr->ifa_next; } // Free the memory allocated by getifaddrs() freeifaddrs(interfaces); } return ipAddress; }
Editor is loading...
Leave a Comment