client.cpp
unknown
c_cpp
9 months ago
6.5 kB
5
Indexable
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <ifaddrs.h>
#include <filesystem>
#define PORT 4444
#define BUFFER_SIZE 1024
using namespace std;
using namespace filesystem;
string getIPAddress();
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 handleFiles(int clientSocket)
{
string input;
cout << "Enter filenames to request (separated by spaces, or 'exit' to quit): ";
getline(cin >> ws, input); // Read full line including spaces
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;
}
string ip_addr_of_recipient = string(response);
sockaddr_in peerServerAddr = {0};
inet_pton(AF_INET, string(response).c_str(), &peerServerAddr.sin_addr);
peerServerAddr.sin_port = 5555;
peerServerAddr.sin_family = AF_INET;
int peerServerSocket = connect(clientSocket, (struct sockaddr*)&peerServerAddr, sizeof(peerServerAddr));
sendFile(peerServerSocket, 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 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 " << PORT << "...\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(serverSocket, buffer, sizeof(buffer));
string response = string(buffer);
if (response.rfind("Send ", 0) != string::npos)
{
sendFile(serverSocket, response.substr(6));
}
}
}
int main()
{
string IPADRESS = getIPAddress();
vector<string> filesNameList = getFileList("../files");
startServer();
string serverIP;
cout << "Enter server IP: ";
cin >> serverIP;
int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket == -1)
{
cerr << "Failed to create socket.\n";
return -1;
}
sockaddr_in serverAddr{};
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
inet_pton(AF_INET, serverIP.c_str(), &serverAddr.sin_addr);
if (connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == -1)
{
cerr << "Failed to connect to the server.\n";
close(clientSocket);
return -1;
}
// Sending filename and ip to server for storing in databse
string temp = "";
for (auto &k : filesNameList)
{
temp += k + ' ' + IPADRESS + ':';
}
cout << temp << endl;
send(clientSocket, temp.c_str(), temp.length(), 0);
while (true)
{
if (handleFiles(clientSocket))
{
break;
}
}
string exitCommand = "exit";
send(clientSocket, exitCommand.c_str(), exitCommand.size(), 0);
close(clientSocket);
return 0;
}
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