// // Created by PeterDwyer on 28/07/2025. // #include "server01.h" #include #include #include #include #include #include #include #include #include "data.h" #define IS_PRIME "{\"method\":\"isPrime\",\"prime\":true}\n" #define IS_NOT_PRIME "{\"method\":\"isPrime\",\"prime\":false}\n" #define IS_PRIME_ERROR "{\"method\":\"isPrime\",\"error\":true}\n" int main() { SOCKET server = get_listen_socket(); SOCKADDR_IN clientAddr; SOCKET client; int clientAddrSize = sizeof(clientAddr); int connection_number = 1; printf("Listening for incoming connections...\n"); while((client = accept(server, (SOCKADDR *)&clientAddr, &clientAddrSize)) != INVALID_SOCKET) { handle_args_t *args = malloc(sizeof(handle_args_t)); args->client = client; args->connection = connection_number++; pthread_t thread; pthread_create(&thread, nullptr, handle_connection, args); } return 0; } void *handle_connection(void *args) { handle_args_t *handleArgs = args; char buffer[1024] = {0}; int bytesReceived; char_array_t *data = char_array_create(1024); while ((bytesReceived = recv(handleArgs->client, buffer, sizeof(buffer), 0)) > 0) { printf("Client sent {%d}: |%d| \n", handleArgs->connection, bytesReceived); char_array_append(data, buffer, bytesReceived); char *request; while ((request = char_array_get_until_char(data, '\n')) != NULL) { parse_request(handleArgs, request, data); } memset(buffer, 0, sizeof(buffer)); } free(handleArgs); pthread_exit(NULL); } void parse_request(handle_args_t *handleArgs, const char *request, char_array_t *data) { if (request != NULL) { const json_object *obj = json_tokener_parse(request); if (obj == NULL) { printf("{%d} Failed to parse json\n", handleArgs->connection); send(handleArgs->client, IS_PRIME_ERROR, strlen(IS_PRIME_ERROR), 0); char_array_destroy(data); closesocket(handleArgs->client); pthread_exit(NULL); } json_object *method_obj = json_object_object_get(obj, "method"); json_object *number_obj = json_object_object_get(obj, "number"); if (method_obj == NULL || number_obj == NULL) { printf("{%d} Missing Fields\n", handleArgs->connection); send(handleArgs->client, IS_PRIME_ERROR, strlen(IS_PRIME_ERROR), 0); char_array_destroy(data); closesocket(handleArgs->client); pthread_exit(NULL); } const int number_type = json_object_get_type(number_obj); if (!(json_object_is_type(method_obj, json_type_string) && (number_type== json_type_double || number_type == json_type_int))) { printf("{%d} Fields Wrong Type\n", handleArgs->connection); send(handleArgs->client, IS_PRIME_ERROR, strlen(IS_PRIME_ERROR), 0); char_array_destroy(data); closesocket(handleArgs->client); pthread_exit(NULL); } const char *method = json_object_get_string(method_obj); if (strcmp(method, "isPrime") != 0) { printf("{%d} Invalid method\n", handleArgs->connection); send(handleArgs->client, IS_PRIME_ERROR, strlen(IS_PRIME_ERROR), 0); char_array_destroy(data); closesocket(handleArgs->client); } if (number_type == json_type_double) { printf("{%d} Floats cannot be prime\n", handleArgs->connection); send(handleArgs->client, IS_NOT_PRIME, strlen(IS_NOT_PRIME), 0); } const int number = json_object_get_int(number_obj); bool number_is_prime; if (number == INT32_MAX) { number_is_prime = false; } else { number_is_prime = is_prime(number); } printf("{%d} '%d' is prime: %d\n", handleArgs->connection, number, number_is_prime); char *response = number_is_prime ? IS_PRIME : IS_NOT_PRIME; send(handleArgs->client, response, strlen(response), 0); } } bool is_prime(const int number) { if (number == 2) { return true; } if (number < 2 || number % 2 == 0) { return false; } const int limit = (int)sqrt(number); for (int i = 3; i <= limit; i+=2) { if (number % i == 0) { return false; } } return true; }