client.cpp

 avatar
unknown
c_cpp
a month ago
6.5 kB
2
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