// // Created by PeterDwyer on 30/07/2025. // #include "server04.h" #include #include #include #include "data.h" #include #include #define BUF_SIZE 1024 int main() { const SOCKET server = get_listen_socket_udp(); SOCKADDR_IN clientAddr; SOCKET client; int clientAddrSize = sizeof(clientAddr); int connection_number = 1; char *request = malloc(BUF_SIZE); char buffer[BUF_SIZE] = {0}; data_map_t *data = data_map_create(1024); printf("Listening for incoming connections...\n"); while (true) { int bytesReceived = recvfrom(server, buffer, sizeof(buffer), 0, (SOCKADDR *) &clientAddr, &clientAddrSize); const char *equals = "="; size_t pos; // IN_ADDR addr = clientAddr.sin_addr; // printf("{%d} Client ip: |%d.%d.%d.%d| \n", connection_number, addr.S_un.S_un_b.s_b1, addr.S_un.S_un_b.s_b2, addr.S_un.S_un_b.s_b3, addr.S_un.S_un_b.s_b4); // printf("{%d} Client port: |%d| \n", connection_number, clientAddr.sin_port); printf("{%d} Client sent: |%s| \n", connection_number, buffer); if ((pos = strcspn(buffer, equals)) != strlen(buffer)) { key_value_t *kv = malloc(sizeof(key_value_t)); kv->key = malloc(sizeof(char)*1024); kv->value = malloc(sizeof(char)*1024); strncpy_s(kv->key, BUF_SIZE, buffer, pos); strncpy_s(kv->value, BUF_SIZE, buffer + sizeof(char)*(pos+1), sizeof(buffer) - pos - 1); data_map_insert_kv(data, kv); printf("{%d} Key: |%s| Value: |%s| \n", connection_number, kv->key, kv->value); } else { printf("{%d} Client query: |%s| \n", connection_number, buffer); char *value = data_map_get(data, buffer); if (strcmp(buffer, "version") == 0) { const char *version = "version=Ken's Key-Value Store 1.0"; sendto(server, version, strlen(version), 0, (SOCKADDR *) &clientAddr, clientAddrSize); } else { sprintf(buffer, "%s=%s", buffer, value); sendto(server, buffer, strlen(buffer), 0, (SOCKADDR *) &clientAddr, clientAddrSize); } } // sendto(server, buffer, bytesReceived, 0, (SOCKADDR *) &clientAddr, clientAddrSize); // strncpy_s(request, BUF_SIZE, buffer, bytesReceived); // printf("{%d} Client sent: |%s| \n", connection_number, request); connection_number++; memset(buffer, 0, sizeof(buffer)); } data_map_free(data); free(request); return 0; } data_map_t *data_map_create(const int capacity) { data_map_t *map = malloc(sizeof(data_map_t)); map->capacity = capacity; map->count = 0; map->data = calloc(capacity, sizeof(key_value_t)); return map; } void data_map_free(data_map_t *map) { for (int i = 0; i < map->count; i++) { free(map->data[i].key); free(map->data[i].value); } free(map->data); free(map); } void data_map_insert_kv(data_map_t *map, key_value_t *kv) { if (map==NULL || map->data == NULL) { exit(1); } for (int i = 0; i < map->count; i++) { if (strcmp(map->data[i].key, kv->key) == 0) { map->data[i].value = kv->value; return; } } const size_t new_size = map->count + 1; if (new_size > map->capacity) { map->capacity = map->capacity+1024; key_value_t *new_array = realloc(map->data, map->capacity * sizeof(key_value_t)); map->data = new_array; } map->data[map->count] = *kv; map->count = new_size; } void data_map_append(data_map_t *map, char *key, char *value) { if (map->data == NULL) { exit(1); } const size_t new_size = map->count + 1; if (new_size > map->capacity) { map->capacity = map->capacity+1024; key_value_t *new_array = realloc(map->data, map->capacity * sizeof(key_value_t)); map->data = new_array; if (map->data == NULL) { printf("Failed to allocate memory for array\n"); } } map->data[map->count].key = key; map->data[map->count].value = value; map->count = new_size; } void data_map_insert(data_map_t *map, char *key, char *value) { if (map->data == NULL) { exit(1); } for (int i = 0; i < map->count; i++) { if (strcmp(map->data[i].key, key) == 0) { map->data[i].value = value; return; } } data_map_append(map, key, value); } char *data_map_get(const data_map_t *map, const char *key) { for (int i = 0; i < map->count; i++) { if (strcmp(map->data[i].key, key) == 0) { return map->data[i].value; } } return ""; }