Files
protohackersc/server02.c

127 lines
4.4 KiB
C

//
// Created by Ajurna on 28/07/2025.
//
#include "server02.h"
#include <winsock2.h>
#include <stdio.h>
#include "data.h"
#include <pthread.h>
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);
price_array_t *prices = price_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);
query_or_insert_t *request;
while ((request = fix_message(char_array_get_bytes(data, 9))) != NULL) {
//parse_request(handleArgs, request, data);
switch (request->insert.type) {
case INSERT:
printf("{%d} timestamp: %d, price: %d\n", handleArgs->connection, request->insert.timestamp, request->insert.price);
price_array_append(prices, &request->insert);
break;
case QUERY:
printf("{%d} Query min: %d, max: %d\n", handleArgs->connection, request->query.mintime, request->query.maxtime);
int average = price_array_query(prices, &request->query);
printf("{%d} Query min: %d, max: %d avg %d\n", handleArgs->connection, request->query.mintime, request->query.maxtime, average);
int32_t response = htonl(average);
send(handleArgs->client, (char*)&response, sizeof(response), 0);
default:
closesocket(handleArgs->client);
free(handleArgs);
pthread_exit(NULL);
exit(3);
}
// free(request);
}
memset(buffer, 0, sizeof(buffer));
}
closesocket(handleArgs->client);
free(handleArgs);
pthread_exit(NULL);
}
query_or_insert_t *fix_message(char *message) {
if (message == NULL) {
return NULL;
}
query_or_insert_t *ret = malloc(sizeof(query_or_insert_t));
ret->insert.type = message[0];
ret->query.mintime = message[4] | (message[3] << 8) | (message[2] << 16) | (message[1] << 24);
ret->query.maxtime = message[8] | (message[7] << 8) | (message[6] << 16) | (message[5] << 24);
return ret;
}
price_array_t *price_array_create(int capacity) {
price_array_t *array = malloc(sizeof(price_array_t));
array->capacity = capacity;
array->size = 0;
array->data = calloc(capacity, sizeof(price_t));
return array;
};
void price_array_free(price_array_t *array) {
free(array->data);
free(array);
};
void price_array_append(price_array_t *array, insert_t *value) {
if (array->data == NULL) {
exit(1);
}
size_t new_size = array->size + 1;
if (new_size > array->capacity) {
array->capacity = array->capacity+1024;
price_t *new_array = realloc(array->data, array->capacity);
array->data = new_array;
if (array->data == NULL) {
printf("Failed to allocate memory for array\n");
exit(1);
}
}
price_t *temp = malloc(sizeof(price_t));
temp->timestamp = value->timestamp;
temp->price = value->price;
array->data[array->size] = *temp;
array->size = new_size;
};
int price_array_query(price_array_t *array, query_t *query) {
int count = 0;
int total = 0;
for (int i = 0; i < array->size; i++) {
if (array->data[i].timestamp >= query->mintime && array->data[i].timestamp <= query->maxtime) {
count++;
total += array->data[i].price;
}
}
printf("{%d} Found %d prices\n", query->mintime, count);
int ret;
if (count == 0) {
ret = 0;
} else {
ret = total/count;
}
return ret;
};