Untitled
unknown
plain_text
7 months ago
8.3 kB
5
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