Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
client.cpp 4.28 KiB
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <vector>
#include <cstdlib>
#include <ctime>

pid_t pid = getpid();

std::string generateRandomKey() {
    return "key" + std::to_string(rand() % 10000);
}


std::string generateRandomValue() {
    return "value" + std::to_string(rand() % 10000);
}

std::string createRandomMessage() {
    char operations[] = {'s', 'g', 'd'};
    char operation = operations[rand() % 3];
    std::string key = generateRandomKey();
    
    if (operation == 's') {
        return "s," + key + "," + generateRandomValue() + ";";
    } else {
        return std::string(1, operation) + "," + key + ";";
    }
}

std::vector<std::string> generateRequests(int requestCount, std::string requestGenerationType) {
    std::vector<std::string> requests;
    requests.reserve(requestCount);
    
    if (requestGenerationType == "random") {
        for (int i = 0; i < requestCount; i++) {
            requests.push_back(createRandomMessage());
        }
    } else if (requestGenerationType == "equal") {
        int getCount = requestCount * 0.33;
        int storeCount = requestCount * 0.33;
        int deleteCount = requestCount * 0.33;

        for (int i = 0; i < getCount; i++) {
            requests.push_back("s,key" + std::to_string(pid) + std::to_string(i) + ",value" + std::to_string(i) + ";");
        }
        for (int i = 0; i < storeCount; i++) {
            requests.push_back("g,key" + std::to_string(pid) + std::to_string(i) +';');
        }
        for (int i = 0; i < deleteCount; i++) {
            requests.push_back("d,key" + std::to_string(pid) + std::to_string(i)  + ';');
        }
    } else if (requestGenerationType == "realistic") {
        int getCount = requestCount * 0.7;
        int storeCount = requestCount * 0.25;
        int deleteCount = requestCount - (getCount + storeCount); // Restliche 5%

        for (int i = 0; i < getCount; i++) {
            requests.push_back("g," + generateRandomKey() + ";");
        }
        for (int i = 0; i < storeCount; i++) {
            requests.push_back("s," + generateRandomKey() + "," + generateRandomValue() + ";");
        }
        for (int i = 0; i < deleteCount; i++) {
            requests.push_back("d," + generateRandomKey() + ";");
        }

        // Um eine realistischere Last zu simulieren, die Reihenfolge zufällig mischen
        //std::random_shuffle(requests.begin(), requests.end());
    } else {
        std::cerr << "requestGenerationType is not expected. Please use [random, equal, realistic]" << std::endl;
    }
    return requests;
}


int main(int argc, char* argv[]) {
    if (argc != 6) {
        std::cerr << "Usage: " << argv[0] << " <server_ip> <port> <buffer_size> <request_count> <requestGenerationType [random, equal, realistic]>" << std::endl;
        return EXIT_FAILURE;
    }

    std::string serverIp = argv[1];
    int port = std::stoi(argv[2]);
    int bufferSize = std::stoi(argv[3]);
    int requestCount = std::stoi(argv[4]);
    std::string requestGenerationType = argv[5];

    srand(time(nullptr));

    std::vector<std::string> requests = generateRequests(requestCount, requestGenerationType);

    int sock;
    struct sockaddr_in server_address;
    
    char buffer[bufferSize] = {0};

    // Socket erstellen
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("Socket failed");
        return EXIT_FAILURE;
    }

    // Serveradresse konfigurieren
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(port);
    if (inet_pton(AF_INET, serverIp.c_str(), &server_address.sin_addr) <= 0) {
        perror("Invalid address");
        return EXIT_FAILURE;
    }

    // Verbindung zum Server herstellen
    if (connect(sock, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
        perror("Connection failed");
        return EXIT_FAILURE;
    }

    for (const auto& message : requests) {
        send(sock, message.c_str(), message.size(), 0);
        std::cout << "Sent: " << message << std::endl;

        ssize_t bytes_received = read(sock, buffer, bufferSize);
        if (bytes_received > 0) {
            std::cout << "Server Response: " << buffer << std::endl;
        }
        memset(buffer, 0, bufferSize);
    }

    std::cout << "Closing connection..." << std::endl;
    close(sock);
    return 0;
}