Skip to content
Snippets Groups Projects
Commit ac4bb3ae authored by Saif Eddine Askri's avatar Saif Eddine Askri
Browse files

push Client version 1.0.0

parent ce34bce8
No related branches found
No related tags found
No related merge requests found
...@@ -42,10 +42,6 @@ ...@@ -42,10 +42,6 @@
"request": "launch", "request": "launch",
"program": "${workspaceFolder}/build/src/myclient", "program": "${workspaceFolder}/build/src/myclient",
"args": [ "args": [
"store",
"id",
"5"
], ],
"stopAtEntry": false, "stopAtEntry": false,
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
"stop_token": "cpp", "stop_token": "cpp",
"streambuf": "cpp", "streambuf": "cpp",
"thread": "cpp", "thread": "cpp",
"typeinfo": "cpp" "typeinfo": "cpp",
"map": "cpp"
} }
} }
\ No newline at end of file
...@@ -2,39 +2,38 @@ ...@@ -2,39 +2,38 @@
#include <cstring> #include <cstring>
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <vector>
#include <cstdlib>
#include <ctime>
//#define SERVER_IP "141.100.42.11"
#define SERVER_IP "127.0.0.1" #define SERVER_IP "127.0.0.1"
#define PORT 2525 #define PORT 2525
#define BUFFER_SIZE 1024 #define BUFFER_SIZE 1024
#define REQUEST_COUNT 70000
std::string createMessage(const std::string& operation, const std::string& key, const std::string& value = "") { std::string generateRandomKey() {
if (operation == "store") { return "key" + std::to_string(rand() % 1000);
return "s," + key + "," + value + ";";
} else if (operation == "get") {
return "g," + key + ";"; // Klammern entfernt
} else if (operation == "delete") {
return "d," + key + ";";
}
return "";
} }
int main(int argc, char* argv[]) { std::string generateRandomValue() {
return "value" + std::to_string(rand() % 10000);
}
if (argc < 3 || argc > 4) { std::string createRandomMessage() {
std::cerr << "Usage: " << argv[0] << " <operation> <key> [value]" << std::endl; char operations[] = {'s', 'g', 'd'};
return 1; char operation = operations[rand() % 3];
std::string key = generateRandomKey();
if (operation == 's') {
return "s," + key + "," + generateRandomValue() + ";";
} else {
return std::string(1, operation) + "," + key + ";";
} }
}
std::string operation = argv[1]; int main() {
std::string key = argv[2]; srand(time(nullptr));
std::string value = (argc == 4) ? argv[3] : "";
//######################### Socket Erstellen #########################
int sock; int sock;
struct sockaddr_in server_address; struct sockaddr_in server_address;
char buffer[BUFFER_SIZE] = {0}; char buffer[BUFFER_SIZE] = {0};
...@@ -49,36 +48,30 @@ int main(int argc, char* argv[]) { ...@@ -49,36 +48,30 @@ int main(int argc, char* argv[]) {
// Serveradresse konfigurieren // Serveradresse konfigurieren
server_address.sin_family = AF_INET; server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT); server_address.sin_port = htons(PORT);
// IP-Adresse konvertieren
if (inet_pton(AF_INET, SERVER_IP, &server_address.sin_addr) <= 0) { if (inet_pton(AF_INET, SERVER_IP, &server_address.sin_addr) <= 0) {
perror("Invalid address"); perror("Invalid address");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
//######################### Verbindung Aufbauen #########################
// Verbindung zum Server herstellen // Verbindung zum Server herstellen
if (connect(sock, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) { if (connect(sock, (struct sockaddr*)&server_address, sizeof(server_address)) < 0) {
perror("Connection failed"); perror("Connection failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
//######################### Request abschicken #########################
// Nachricht basierend auf den Argumenten erstellen for (int i = 0; i < REQUEST_COUNT; i++) {
std::string message = createMessage(operation, key, value); std::string message = createRandomMessage();
if (message.empty()) { send(sock, message.c_str(), message.size(), 0);
std::cerr << "Invalid operation! Use 'store', 'get', or 'delete'." << std::endl; std::cout << "Sent: " << message << std::endl;
return 1;
} ssize_t bytes_received = read(sock, buffer, BUFFER_SIZE);
// Nachricht senden if (bytes_received > 0) {
send(sock, message.c_str(), message.size(), 0); std::cout << "Server: " << buffer << std::endl;
std::cout << "Message sent: " << message << std::endl; }
//######################### Antwort empfangen ######################### memset(buffer, 0, BUFFER_SIZE);
// Antwort empfangen
ssize_t bytes_received = read(sock, buffer, BUFFER_SIZE);
if (bytes_received > 0) {
std::cout << "Server: " << buffer << std::endl;
} }
//######################### Client Beenden #########################
// Socket schließen std::cout << "Closing connection..." << std::endl;
close(sock); close(sock);
return 0; return 0;
} }
...@@ -8,25 +8,17 @@ ...@@ -8,25 +8,17 @@
#include <map> #include <map>
#define PORT 2525 #define PORT 2525
#define BUFFER_SIZE 1024 #define BUFFER_SIZE 1024
#define STORE_OPERATION 's' #define STORE_OPERATION 's'
#define GET_OPERATION 'g' #define GET_OPERATION 'g'
#define DELETE_OPERATION 'd' #define DELETE_OPERATION 'd'
//=========== SLOW PARSER ====================
struct Request { struct Request {
char operation; char operation;
std::string key; std::string key;
std::string value; std::string value;
}; };
std::mutex mtx;
std::map<std::string,std::string> DB;
Request* parseRequest(const char* buffer) { Request* parseRequest(const char* buffer) {
// Create a new Request struct // Create a new Request struct
Request* req = new Request(); Request* req = new Request();
...@@ -63,52 +55,116 @@ std::map<std::string,std::string> DB; ...@@ -63,52 +55,116 @@ std::map<std::string,std::string> DB;
return req; return req;
} }
//=============================================
std::mutex mtx;
std::map<std::string, std::string> DB;
// we assume that this function is slow
std::string processRequest_slow(const std::string& request) {
std::string response;
Request* parsedRequest = parseRequest(request.c_str());
std::lock_guard<std::mutex> lock(mtx);
switch (parsedRequest->operation) {
case STORE_OPERATION:
DB[parsedRequest->key] = parsedRequest->value;
response = "Stored [" + parsedRequest->key + "] = " + parsedRequest->value;
break;
case GET_OPERATION:
if (DB.find(parsedRequest->key) != DB.end()) {
response = "Value of [" + parsedRequest->key + "] is " + DB[parsedRequest->key];
} else {
response = "Key [" + parsedRequest->key + "] not found";
}
break;
case DELETE_OPERATION:
if (DB.erase(parsedRequest->key)) {
response = "Deleted key [" + parsedRequest->key + "]";
} else {
response = "Key [" + parsedRequest->key + "] not found for deletion";
}
break;
default:
response = "Invalid operation!";
break;
}
void handle_client(int client_socket) { return response;
char buffer[BUFFER_SIZE] = {0}; }
// there is parsing problem the parced key is always with ; at the end
std::string processRequest(const std::string& request) {
std::string response;
// Nachricht vom Client empfangen size_t first = request.find(",");
ssize_t bytes_received = read(client_socket, buffer, BUFFER_SIZE); size_t second = request.find(",", first + 1);
size_t end = request.find(";");
if (first == std::string::npos || end == std::string::npos) {
return "Bad request!";
}
if (bytes_received > 0) { char operation = request[0];
//std::cout << "Client: " << buffer << std::endl; std::string key;
std::string value;
Request* request = parseRequest(buffer); if (second != std::string::npos) {
std::string response; // Extract key without ';'
key = request.substr(first + 1, second - first - 1);
value = request.substr(second + 1, end - second - 1);
} else {
// Extract key correctly without including ';'
key = request.substr(first + 1, end - first - 1);
}
if(request->operation == STORE_OPERATION){ std::lock_guard<std::mutex> lock(mtx);
std::lock_guard<std::mutex> lock(mtx);
DB[request->key] = request->value; switch (operation) {
response = "freue dich :)"; case STORE_OPERATION:
}else if (request->operation == GET_OPERATION){ DB[key] = value;
response = "Stored [" + key + "] = " + value;
std::lock_guard<std::mutex> lock(mtx); break;
auto it = DB.find(request->key); case GET_OPERATION:
if (it != DB.end()) { if (DB.find(key) != DB.end()) {
response = "The Value of the [" + request->key + "] is => " + it->second; response = "Value of [" + key + "] is " + DB[key];
}else{ } else {
response = "Key [" + request->key +"] Not Found"; response = "Key [" + key + "] not found";
} }
break;
}else if (request->operation == DELETE_OPERATION){ case DELETE_OPERATION:
std::lock_guard<std::mutex> lock(mtx); if (DB.erase(key)) {
if(DB.erase(request->key) != 0){ response = "Deleted key [" + key + "]";
response = "Item with Key [" + request->key +"] is deleted"; } else {
}else{ response = "Key [" + key + "] not found for deletion";
response = "Key " + request->key +" Not Found for [delete]";
} }
}else{ break;
response = "bad request -_____- !"; default:
response = "Invalid operation!";
break;
}
return response;
}
void handle_client(int client_socket) {
char buffer[BUFFER_SIZE] = {0};
while (true) { // the Thread is allways active
ssize_t bytes_received = read(client_socket, buffer, BUFFER_SIZE - 1);
if (bytes_received <= 0) {
std::cout << "Client disconnected." << std::endl;
break;
} }
// send Response buffer[bytes_received] = '\0';
send(client_socket, response.c_str(), strlen(response.c_str()), 0); std::string response = processRequest(buffer);
send(client_socket, response.c_str(), response.size(), 0);
} }
// Socket schließen
close(client_socket); close(client_socket);
} }
...@@ -117,25 +173,21 @@ int main() { ...@@ -117,25 +173,21 @@ int main() {
struct sockaddr_in address; struct sockaddr_in address;
socklen_t addrlen = sizeof(address); socklen_t addrlen = sizeof(address);
// Socket erstellen
server_fd = socket(AF_INET, SOCK_STREAM, 0); server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd == -1) { if (server_fd == -1) {
perror("Socket failed"); perror("Socket failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Serveradresse festlegen
address.sin_family = AF_INET; address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY; address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT); address.sin_port = htons(PORT);
// Socket an Port binden
if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) { if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
perror("Bind failed"); perror("Bind failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// Server lauscht auf eingehende Verbindungen
if (listen(server_fd, 5) < 0) { if (listen(server_fd, 5) < 0) {
perror("Listen failed"); perror("Listen failed");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
...@@ -153,13 +205,9 @@ int main() { ...@@ -153,13 +205,9 @@ int main() {
std::cout << "New client connected" << std::endl; std::cout << "New client connected" << std::endl;
// Starte neuen Thread für den Client
std::thread(handle_client, client_socket).detach(); std::thread(handle_client, client_socket).detach();
} }
close(server_fd); close(server_fd);
return 0; return 0;
} }
#include <iostream> #include <iostream>
#include <string> #include <thread>
#include <cstring> // for strtok and strchr #include <vector>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <mutex>
#include <map>
#define PORT 2525
#define BUFFER_SIZE 1024
#define STORE_OPERATION 's'
#define GET_OPERATION 'g'
#define DELETE_OPERATION 'd'
std::mutex mtx;
std::map<std::string,std::string> DB;
struct Request { struct Request {
char operation; // Operation: 's' (store), 'g' (get), 'd' (delete) char operation;
std::string key; // Key std::string key;
std::string value; // Value (only for store operation) std::string value;
}; };
Request* parseRequest(const char* buffer) {
Request* parseRequest(const char* buffer) {
// Create a new Request struct // Create a new Request struct
Request* req = new Request(); Request* req = new Request();
...@@ -45,36 +64,102 @@ Request* parseRequest(const char* buffer) { ...@@ -45,36 +64,102 @@ Request* parseRequest(const char* buffer) {
return req; return req;
} }
void handle_client(int client_socket) {
char buffer[BUFFER_SIZE] = {0};
// Nachricht vom Client empfangen
ssize_t bytes_received = read(client_socket, buffer, BUFFER_SIZE);
if (bytes_received > 0) {
//std::cout << "Client: " << buffer << std::endl;
Request* request = parseRequest(buffer);
std::string response;
if(request->operation == STORE_OPERATION){
std::lock_guard<std::mutex> lock(mtx);
DB[request->key] = request->value;
response = "freue dich :)";
}else if (request->operation == GET_OPERATION){
std::lock_guard<std::mutex> lock(mtx);
auto it = DB.find(request->key);
if (it != DB.end()) {
response = "The Value of the [" + request->key + "] is => " + it->second;
}else{
response = "Key [" + request->key +"] Not Found";
}
}else if (request->operation == DELETE_OPERATION){
std::lock_guard<std::mutex> lock(mtx);
if(DB.erase(request->key) != 0){
response = "Item with Key [" + request->key +"] is deleted";
}else{
response = "Key " + request->key +" Not Found for [delete]";
}
}else{
response = "bad request -_____- !";
}
// send Response
send(client_socket, response.c_str(), strlen(response.c_str()), 0);
}
// Socket schließen
close(client_socket);
}
int main() { int main() {
// Test cases int server_fd, client_socket;
const char* storeRequest = "s,myKey,myValue;"; struct sockaddr_in address;
const char* getRequest = "g,myKey;"; socklen_t addrlen = sizeof(address);
const char* deleteRequest = "d,myKey;";
// Socket erstellen
// Parse requests server_fd = socket(AF_INET, SOCK_STREAM, 0);
Request* storeReq = parseRequest(storeRequest); if (server_fd == -1) {
Request* getReq = parseRequest(getRequest); perror("Socket failed");
Request* deleteReq = parseRequest(deleteRequest); exit(EXIT_FAILURE);
// Print parsed requests
if (storeReq) {
std::cout << "Store Request: Operation=" << storeReq->operation
<< ", Key=" << storeReq->key
<< ", Value=" << storeReq->value << std::endl;
delete storeReq;
} }
if (getReq) { // Serveradresse festlegen
std::cout << "Get Request: Operation=" << getReq->operation address.sin_family = AF_INET;
<< ", Key=" << getReq->key << std::endl; address.sin_addr.s_addr = INADDR_ANY;
delete getReq; address.sin_port = htons(PORT);
// Socket an Port binden
if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
perror("Bind failed");
exit(EXIT_FAILURE);
} }
if (deleteReq) { // Server lauscht auf eingehende Verbindungen
std::cout << "Delete Request: Operation=" << deleteReq->operation if (listen(server_fd, 5) < 0) {
<< ", Key=" << deleteReq->key << std::endl; perror("Listen failed");
delete deleteReq; exit(EXIT_FAILURE);
} }
std::cout << "Server listening on port " << PORT << std::endl;
while (true) {
client_socket = accept(server_fd, (struct sockaddr*)&address, &addrlen);
if (client_socket < 0) {
perror("Accept failed");
continue;
}
std::cout << "New client connected" << std::endl;
// Starte neuen Thread für den Client
std::thread(handle_client, client_socket).detach();
}
close(server_fd);
return 0; return 0;
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment