124 lines
4.6 KiB
C
124 lines
4.6 KiB
C
//
|
|
// Created by PeterDwyer on 28/07/2025.
|
|
//
|
|
|
|
#include "server01.h"
|
|
|
|
#include <math.h>
|
|
#include <stdio.h>
|
|
#include <json-c/json_tokener.h>
|
|
#include <json-c/json_object.h>
|
|
#include <pthread.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <winsock2.h>
|
|
#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 serverAddr, clientAddr;
|
|
SOCKET client;
|
|
int clientAddrSize = sizeof(clientAddr);
|
|
int connection_number = 1;
|
|
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));
|
|
}
|
|
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;
|
|
} |