feat(server): added server creation and destruction

This commit is contained in:
Mineplay 2025-12-21 15:16:09 +01:00
parent f8e125308f
commit 968321ab30
3 changed files with 183 additions and 12 deletions

View file

@ -0,0 +1,60 @@
/*
* Copyright (C) Tristan Franssen, <tristanfranssen@strawhats.nl>.
*
* This software is licensed under the Apache License, Version 2.0 (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License in the file LICENSE or at
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef COSMS_CORE_SERVER
#define COSMS_CORE_SERVER
#if defined(_WIN32)
#include <winsock2.h>
#endif
typedef enum {
COSMS_CORE_SERVER_OK = 0,
COSMS_CORE_SERVER_FAILED_TO_CREATE_SOCKET = -1,
COSMS_CORE_SERVER_COULD_NOT_BIND_ADDRESS = -2,
COSMS_CORE_SERVER_UNKNOWN_ERROR = -3
} CosmsCoreServerError;
struct cosms_core_server {
unsigned short port, domain;
int type;
#if defined(__GNUC__)
int listening_socket;
#elif defined(_WIN32)
SOCKET listening_socket;
#endif
};
/**
* @brief Creates a new server of specified type.
*
* @param new_server Pointer to server struct (must not be NULL)
* @param domain The communication domain the server should use
* @param type of communication sementics to use
* @param port to run the server on
* @return COSMS_CORE_SERVER_OK on success, or a negative error code
*/
CosmsCoreServerError cosms_core_server_create(struct cosms_core_server *new_server, unsigned short domain, int type, unsigned short port);
/**
* @brief Stops and destroy's the server.
*
* @param current_server Pointer to an active server struct (must not be NULL)
* @return COSMS_CORE_SERVER_OK on success, or negative error code
*/
CosmsCoreServerError cosms_core_server_destroy(struct cosms_core_server *current_server);
/**
* @brief Converts error code to a string that can be used for printing/logging errors.
*
* @param error The error code to convert to a string message.
* @return The error as a string on success, or NULL
*/
const char *cosms_core_server_error_string(CosmsCoreServerError error);
#endif /* COSMS_CORE_SERVER */

View file

@ -417,40 +417,40 @@ CosmsCoreFileError cosms_core_file_delete(const char *path) {
const char *cosms_core_file_error_string(CosmsCoreFileError error) { const char *cosms_core_file_error_string(CosmsCoreFileError error) {
switch(error) { switch(error) {
case COSMS_CORE_FILE_OK: case COSMS_CORE_FILE_OK:
return "cosms-file everything ok"; return "cosms-core-file everything ok";
case COSMS_CORE_FILE_NOT_FOUND: case COSMS_CORE_FILE_NOT_FOUND:
return "cosms-file path not found"; return "cosms-core-file path not found";
case COSMS_CORE_FILE_NO_ACCESS: case COSMS_CORE_FILE_NO_ACCESS:
return "cosms-file no access"; return "cosms-core-file no access";
case COSMS_CORE_FILE_LIMIT_REACHED: case COSMS_CORE_FILE_LIMIT_REACHED:
return "cosms-file to many open files"; return "cosms-core-file to many open files";
case COSMS_CORE_FILE_COULD_NOT_READ_SIZE: case COSMS_CORE_FILE_COULD_NOT_READ_SIZE:
return "cosms-file failed to read size"; return "cosms-core-file failed to read size";
case COSMS_CORE_FILE_UNKOWN_ERROR: case COSMS_CORE_FILE_UNKOWN_ERROR:
return "cosms-file unkown error occured"; return "cosms-core-file unkown error occured";
case COSMS_CORE_FILE_FAILED_TO_ALLOCATE: case COSMS_CORE_FILE_FAILED_TO_ALLOCATE:
return "cosms-file failed to allocate memory"; return "cosms-core-file failed to allocate memory";
case COSMS_CORE_FILE_FAILED_TO_READ: case COSMS_CORE_FILE_FAILED_TO_READ:
return "cosms-file failed to read content of file"; return "cosms-core-file failed to read content of file";
case COSMS_CORE_FILE_FAILED_TO_WRITE: case COSMS_CORE_FILE_FAILED_TO_WRITE:
return "cosms-file failed to write content to file"; return "cosms-core-file failed to write content to file";
case COSMS_CORE_FILE_STILL_OPEN: case COSMS_CORE_FILE_STILL_OPEN:
return "cosms-file still open"; return "cosms-core-file still open";
case COSMS_CORE_FILE_INVALID_FILE: case COSMS_CORE_FILE_INVALID_FILE:
return "cosms-file invalid native file given"; return "cosms-core-file invalid native file given";
case COSMS_CORE_FILE_INVALID_OPERATION: case COSMS_CORE_FILE_INVALID_OPERATION:
return "cosms-file invalid operation for current file"; return "cosms-core-file invalid operation for current file";
default: default:
return NULL; return NULL;

111
src/networking/server.c Normal file
View file

@ -0,0 +1,111 @@
/*
* Copyright (C) Tristan Franssen, <tristanfranssen@strawhats.nl>.
*
* This software is licensed under the Apache License, Version 2.0 (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License in the file LICENSE or at
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include "cosms-core/networking/server.h"
#if defined(__GNUC__)
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#elif defined(_WIN32)
static int cosms_core_server_initialized_winsock_instances = 0;
#endif
/**
* @brief Creates a new server of specified type.
*/
CosmsCoreServerError cosms_core_server_create(struct cosms_core_server *new_server, unsigned short domain, int type, unsigned short port) {
new_server->domain = domain;
new_server->type = type;
new_server->port = port;
struct sockaddr_in address;
address.sin_family = domain;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
#if defined(__GNUC__)
new_server->listening_socket = socket(domain, type, port);
if (new_server->listening_socket == -1) {
return COSMS_CORE_SERVER_FAILED_TO_CREATE_SOCKET;
}
int result = bind(new_server->listening_socket, (struct sockaddr*)&address, sizeof(address));
if (result == -1) {
return COSMS_CORE_SERVER_COULD_NOT_BIND_ADDRESS;
}
#elif defined(_WIN32)
if (cosms_core_server_initialized_winsock_instances == 0) {
WSADATA data;
if (WSAStartup(MAKEWORD(2, 2), &data) == 0) {
return COSMS_CORE_SERVER_FAILED_TO_CREATE_SOCKET;
}
}
cosms_core_server_initialized_winsock_instances += 1;
new_server->listening_socket = socket(domain, type, port);
if (new_server->listening_socket == INVALID_SOCKET) {
return COSMS_CORE_SERVER_FAILED_TO_CREATE_SOCKET;
}
int result = bind(new_server->listening_socket, (struct sockaddr*)&address, sizeof(address));
if (result == SOCKET_ERROR) {
return COSMS_CORE_SERVER_COULD_NOT_BIND_ADDRESS;
}
#endif
return COSMS_CORE_SERVER_OK;
}
/**
* @brief Stops and destroy's the server.
*/
CosmsCoreServerError cosms_core_server_destroy(struct cosms_core_server *current_server) {
#if defined(__GNUC__)
int result = close(current_server->listening_socket);
if (result == -1) {
return COSMS_CORE_SERVER_UNKNOWN_ERROR;
}
#elif defined(_WIN32)
int result = closesocket(current_server->listening_socket);
if (result == SOCKET_ERROR) {
return COSMS_CORE_SERVER_UNKNOWN_ERROR;
}
cosms_core_server_initialized_winsock_instances -= 1;
if (cosms_core_server_initialized_winsock_instances == 0) {
WSACleanup();
}
#endif
return COSMS_CORE_SERVER_OK;
}
/**
* @brief Converts error code to a string that can be used for printing/logging errors.
*/
const char *cosms_core_server_error_string(CosmsCoreServerError error) {
switch (error) {
case COSMS_CORE_SERVER_OK:
return "cosms-core-server everything ok";
case COSMS_CORE_SERVER_FAILED_TO_CREATE_SOCKET:
return "cosms-core-server failed to create new socket";
case COSMS_CORE_SERVER_COULD_NOT_BIND_ADDRESS:
return "cosms-core-server could not bind address to new socket";
case COSMS_CORE_SERVER_UNKNOWN_ERROR:
return "cosms-core-server unkown error occured";
default:
return NULL;
}
}