diff --git a/prak3/.vscode/settings.json b/prak3/.vscode/settings.json index 9c57d8b72bbd26fcccc7fe2b7f8c620532a36f19..73a34f60f86ede5e937cafd345013826445176bb 100644 --- a/prak3/.vscode/settings.json +++ b/prak3/.vscode/settings.json @@ -53,6 +53,7 @@ "streambuf": "cpp", "thread": "cpp", "typeinfo": "cpp", - "map": "cpp" + "map": "cpp", + "shared_mutex": "cpp" } } \ No newline at end of file diff --git a/prak3/src/client.cpp b/prak3/src/client.cpp index 98de7266cb3a6d63baaea398307404d4d1f98eff..34e48da8f681f430edd1ccc001d1e6cf51029df8 100644 --- a/prak3/src/client.cpp +++ b/prak3/src/client.cpp @@ -6,6 +6,8 @@ #include <cstdlib> #include <ctime> +#define HEADER_SIZE 1 + pid_t pid = getpid(); std::string generateRandomKey() { @@ -29,13 +31,24 @@ std::string createRandomMessage() { } } -std::vector<std::string> generateRequests(int requestCount, std::string requestGenerationType) { - std::vector<std::string> requests; +std::vector<std::pair<char*, int>> generateRequests(int requestCount, std::string requestGenerationType) { + std::vector<std::pair<char*, int>> requests; requests.reserve(requestCount); - + if (requestGenerationType == "random") { for (int i = 0; i < requestCount; i++) { - requests.push_back(createRandomMessage()); + std::string message = createRandomMessage(); + + // Schritt 1: Länge der Nachricht in ein Byte packen + uint8_t body_length = static_cast<uint8_t>(message.length()); + + // Schritt 2: Puffer erstellen und Daten packen + char* message_to_send_ptr = new char[HEADER_SIZE + message.length()]; + message_to_send_ptr[0] = body_length; // Header: Länge der Nachricht + std::memcpy(message_to_send_ptr + HEADER_SIZE, message.c_str(), message.length()); // Nachrichtenkörper + + // Schritt 3: Puffer und Größe in den Vektor speichern + requests.push_back({message_to_send_ptr, HEADER_SIZE + static_cast<int>(message.length())}); } } else if (requestGenerationType == "equal") { int getCount = requestCount * 0.33; @@ -43,13 +56,28 @@ std::vector<std::string> generateRequests(int requestCount, std::string requestG 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) + ";"); + std::string message = "s,key" + std::to_string(getpid()) + std::to_string(i) + ",value" + std::to_string(i) + ";"; + uint8_t body_length = static_cast<uint8_t>(message.length()); + char* message_to_send_ptr = new char[HEADER_SIZE + message.length()]; + message_to_send_ptr[0] = body_length; + std::memcpy(message_to_send_ptr + HEADER_SIZE, message.c_str(), message.length()); + requests.push_back({message_to_send_ptr, HEADER_SIZE + static_cast<int>(message.length())}); } for (int i = 0; i < storeCount; i++) { - requests.push_back("g,key" + std::to_string(pid) + std::to_string(i) +';'); + std::string message = "g,key" + std::to_string(getpid()) + std::to_string(i) + ';'; + uint8_t body_length = static_cast<uint8_t>(message.length()); + char* message_to_send_ptr = new char[HEADER_SIZE + message.length()]; + message_to_send_ptr[0] = body_length; + std::memcpy(message_to_send_ptr + HEADER_SIZE, message.c_str(), message.length()); + requests.push_back({message_to_send_ptr, HEADER_SIZE + static_cast<int>(message.length())}); } for (int i = 0; i < deleteCount; i++) { - requests.push_back("d,key" + std::to_string(pid) + std::to_string(i) + ';'); + std::string message = "d,key" + std::to_string(getpid()) + std::to_string(i) + ';'; + uint8_t body_length = static_cast<uint8_t>(message.length()); + char* message_to_send_ptr = new char[HEADER_SIZE + message.length()]; + message_to_send_ptr[0] = body_length; + std::memcpy(message_to_send_ptr + HEADER_SIZE, message.c_str(), message.length()); + requests.push_back({message_to_send_ptr, HEADER_SIZE + static_cast<int>(message.length())}); } } else if (requestGenerationType == "realistic") { int getCount = requestCount * 0.7; @@ -57,20 +85,33 @@ std::vector<std::string> generateRequests(int requestCount, std::string requestG int deleteCount = requestCount - (getCount + storeCount); // Restliche 5% for (int i = 0; i < getCount; i++) { - requests.push_back("g," + generateRandomKey() + ";"); + std::string message = "g," + generateRandomKey() + ";"; + uint8_t body_length = static_cast<uint8_t>(message.length()); + char* message_to_send_ptr = new char[HEADER_SIZE + message.length()]; + message_to_send_ptr[0] = body_length; + std::memcpy(message_to_send_ptr + HEADER_SIZE, message.c_str(), message.length()); + requests.push_back({message_to_send_ptr, HEADER_SIZE + static_cast<int>(message.length())}); } for (int i = 0; i < storeCount; i++) { - requests.push_back("s," + generateRandomKey() + "," + generateRandomValue() + ";"); + std::string message = "s," + generateRandomKey() + "," + generateRandomValue() + ";"; + uint8_t body_length = static_cast<uint8_t>(message.length()); + char* message_to_send_ptr = new char[HEADER_SIZE + message.length()]; + message_to_send_ptr[0] = body_length; + std::memcpy(message_to_send_ptr + HEADER_SIZE, message.c_str(), message.length()); + requests.push_back({message_to_send_ptr, HEADER_SIZE + static_cast<int>(message.length())}); } for (int i = 0; i < deleteCount; i++) { - requests.push_back("d," + generateRandomKey() + ";"); + std::string message = "d," + generateRandomKey() + ";"; + uint8_t body_length = static_cast<uint8_t>(message.length()); + char* message_to_send_ptr = new char[HEADER_SIZE + message.length()]; + message_to_send_ptr[0] = body_length; + std::memcpy(message_to_send_ptr + HEADER_SIZE, message.c_str(), message.length()); + requests.push_back({message_to_send_ptr, HEADER_SIZE + static_cast<int>(message.length())}); } - - // 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; } @@ -89,7 +130,7 @@ int main(int argc, char* argv[]) { srand(time(nullptr)); - std::vector<std::string> requests = generateRequests(requestCount, requestGenerationType); + std::vector<std::pair<char*, int>> requests = generateRequests(requestCount, requestGenerationType); int sock; struct sockaddr_in server_address; @@ -118,8 +159,8 @@ int main(int argc, char* argv[]) { } for (const auto& message : requests) { - send(sock, message.c_str(), message.size(), 0); - std::cout << "Sent: " << message << std::endl; + send(sock, message.first, message.second, 0); + std::cout << "Sent: " << message.first << std::endl; ssize_t bytes_received = read(sock, buffer, bufferSize); if (bytes_received > 0) { @@ -132,3 +173,11 @@ int main(int argc, char* argv[]) { close(sock); return 0; } + + + + + + + + diff --git a/prak3/src/server.cpp b/prak3/src/server.cpp index ac239f5677479d7b3d87a68c1bd0570960a35ef4..4c05f6a8f23b449a70a64550ae9661413f7b51e2 100644 --- a/prak3/src/server.cpp +++ b/prak3/src/server.cpp @@ -10,7 +10,9 @@ #include <shared_mutex> #define PORT 2525 -#define BUFFER_SIZE 1024 +#define BODY_BUFFER_SIZE 64 +#define HEADER_SIZE 1 + #define STORE_OPERATION 's' #define GET_OPERATION 'g' #define DELETE_OPERATION 'd' @@ -28,16 +30,6 @@ void throughput_monitor() { } } - - -#include <map> - -#define PORT 2525 -#define BUFFER_SIZE 1024 -#define STORE_OPERATION 's' -#define GET_OPERATION 'g' -#define DELETE_OPERATION 'd' - //=========== SLOW PARSER ==================== struct Request { char operation; @@ -115,7 +107,7 @@ std::string processRequest_slow(const std::string& request) { } // we assume that this function is fast -// gelichzeitig lesen oder schreiben ist erlaubt +// gelichzeitig lesen aber nur einmal schreiben std::string processRequest_fast(const std::string& request) { std::string response; @@ -225,31 +217,52 @@ std::string processRequest_shared_mtx(const std::string& request) { return response; } + void handle_client(int client_socket) { - char buffer[BUFFER_SIZE] = {0}; - - while (true) { - + + while (true) { // warte bis der Client die Verbindung trennt + + char body_buffer[BODY_BUFFER_SIZE] = {0}; + ssize_t body_length = 0; ssize_t bytes_received = 0; ssize_t total_bytes_received = 0; - while (true) { - bytes_received = read(client_socket, buffer + total_bytes_received, 1); + + uint8_t body_lenght_byte ; + + while (bytes_received < HEADER_SIZE) + { + // read header + bytes_received = read(client_socket, &body_lenght_byte , HEADER_SIZE); if (bytes_received <= 0) { std::cout << "Client disconnected." << std::endl; return; } - total_bytes_received += bytes_received; - if (buffer[total_bytes_received - 1] == ';') { - break; + } + + body_length = static_cast<int>(body_lenght_byte); + + std::string response; + if (body_length != 0) { + + bytes_received = 0; + total_bytes_received = 0; + // read body + while (total_bytes_received < body_length) { + ssize_t bytes_received = read(client_socket, body_buffer + total_bytes_received, body_length - total_bytes_received); + if (bytes_received <= 0) { + std::cout << "Client disconnected while reading body." << std::endl; + return; + } + total_bytes_received += bytes_received; } + response = processRequest_shared_mtx(body_buffer); + }else{ + response = "Bad request!"; } - std::string response = processRequest_shared_mtx(buffer); - // Anfragezähler inkrementieren request_count.fetch_add(1, std::memory_order_relaxed); - send(client_socket, response.c_str(), response.size(), 0); }