feat(server): added receive function for udp and tcp servers

This commit is contained in:
Mineplay 2025-12-21 22:10:46 +01:00
parent fe7fea1c94
commit 8c4cf93f33
2 changed files with 60 additions and 14 deletions

View file

@ -16,10 +16,13 @@
#endif #endif
typedef enum { typedef enum {
COSMS_CORE_SERVER_CONNECTION_CLOSED = 1,
COSMS_CORE_SERVER_OK = 0, COSMS_CORE_SERVER_OK = 0,
COSMS_CORE_SERVER_FAILED_TO_CREATE_SOCKET = -1, COSMS_CORE_SERVER_FAILED_TO_CREATE_SOCKET = -1,
COSMS_CORE_SERVER_COULD_NOT_BIND_ADDRESS = -2, COSMS_CORE_SERVER_COULD_NOT_BIND_ADDRESS = -2,
COSMS_CORE_SERVER_UNKNOWN_ERROR = -3 COSMS_CORE_SERVER_UNKNOWN_ERROR = -3,
COSMS_CORE_SERVER_TYPE_NOT_SUPPORTED = -4,
COSMS_CORE_SERVER_FAILED_TO_RECEIVE = -5
} CosmsCoreServerError; } CosmsCoreServerError;
struct cosms_core_server { struct cosms_core_server {
@ -33,6 +36,17 @@ struct cosms_core_server {
#endif #endif
}; };
struct cosms_core_server_client {
struct sockaddr_in address;
int address_length;
#if defined(__linux__)
int socket;
#elif defined(_WIN32)
SOCKET socket;
#endif
};
/** /**
* @brief Creates a new server of specified type. * @brief Creates a new server of specified type.
* *
@ -51,6 +65,18 @@ CosmsCoreServerError cosms_core_server_create(struct cosms_core_server *new_serv
*/ */
CosmsCoreServerError cosms_core_server_destroy(struct cosms_core_server *current_server); CosmsCoreServerError cosms_core_server_destroy(struct cosms_core_server *current_server);
/**
* @brief Receives message from client.
*
* @param current_server Pointer to active server struct (must not be NULL)
* @param client Pointer to client struct (must be connected to server when using tcp)
* @param buffer to store the received message in (must not be NULL)
* @param buffer_size the size of the buffer to store the message in
* @param received_bytes the amount of bytes received from the client (can be NULL)
* @return COSMS_CORE_SERVER_OK or COSMS_CORE_SERVER_CONNECTION_CLOSED on success, or negative error code
*/
CosmsCoreServerError cosms_core_server_receive(struct cosms_core_server *current_server, struct cosms_core_server_client *client, char *buffer, unsigned int buffer_size, unsigned int *received_bytes);
/** /**
* @brief Converts error code to a string that can be used for printing/logging errors. * @brief Converts error code to a string that can be used for printing/logging errors.
* *

View file

@ -7,6 +7,7 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
#include "cosms-core/networking/server.h" #include "cosms-core/networking/server.h"
#include <winsock2.h>
#if defined(__linux__) #if defined(__linux__)
#include <unistd.h> #include <unistd.h>
@ -27,17 +28,7 @@ CosmsCoreServerError cosms_core_server_create(struct cosms_core_server *new_serv
address.sin_addr.s_addr = INADDR_ANY; address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port); address.sin_port = htons(port);
#if defined(__linux__) #if defined(_WIN32)
new_server->listening_socket = socket(domain, type, 0);
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) { if (cosms_core_server_initialized_winsock_instances == 0) {
WSADATA data; WSADATA data;
if (WSAStartup(MAKEWORD(2, 2), &data) == 0) { if (WSAStartup(MAKEWORD(2, 2), &data) == 0) {
@ -46,6 +37,7 @@ CosmsCoreServerError cosms_core_server_create(struct cosms_core_server *new_serv
} }
cosms_core_server_initialized_winsock_instances += 1; cosms_core_server_initialized_winsock_instances += 1;
#endif
new_server->listening_socket = socket(domain, type, 0); new_server->listening_socket = socket(domain, type, 0);
if (new_server->listening_socket == INVALID_SOCKET) { if (new_server->listening_socket == INVALID_SOCKET) {
@ -53,10 +45,9 @@ CosmsCoreServerError cosms_core_server_create(struct cosms_core_server *new_serv
} }
int result = bind(new_server->listening_socket, (struct sockaddr*)&address, sizeof(address)); int result = bind(new_server->listening_socket, (struct sockaddr*)&address, sizeof(address));
if (result == SOCKET_ERROR) { if (result == -1) {
return COSMS_CORE_SERVER_COULD_NOT_BIND_ADDRESS; return COSMS_CORE_SERVER_COULD_NOT_BIND_ADDRESS;
} }
#endif
return COSMS_CORE_SERVER_OK; return COSMS_CORE_SERVER_OK;
} }
@ -85,11 +76,40 @@ CosmsCoreServerError cosms_core_server_destroy(struct cosms_core_server *current
return COSMS_CORE_SERVER_OK; return COSMS_CORE_SERVER_OK;
} }
/**
* @brief Receives message from client.
*/
CosmsCoreServerError cosms_core_server_receive(struct cosms_core_server *current_server, struct cosms_core_server_client *client, char *buffer, unsigned int buffer_size, unsigned int *received_bytes) {
int bytes_received = 0;
if (current_server->type == SOCK_STREAM) {
bytes_received = recv(client->socket, buffer, buffer_size, 0);
} else {
bytes_received = recvfrom(current_server->listening_socket, buffer, buffer_size, 0, (struct sockaddr*)&client->address, &client->address_length);
}
if (bytes_received == -1) {
return COSMS_CORE_SERVER_FAILED_TO_RECEIVE;
}
if (bytes_received == 0) {
return COSMS_CORE_SERVER_CONNECTION_CLOSED;
}
if (received_bytes != NULL) {
(*received_bytes) = bytes_received;
}
return COSMS_CORE_SERVER_OK;
}
/** /**
* @brief Converts error code to a string that can be used for printing/logging errors. * @brief Converts error code to a string that can be used for printing/logging errors.
*/ */
const char *cosms_core_server_error_string(CosmsCoreServerError error) { const char *cosms_core_server_error_string(CosmsCoreServerError error) {
switch (error) { switch (error) {
case COSMS_CORE_SERVER_CONNECTION_CLOSED:
return "cosms-core-server connection was closed";
case COSMS_CORE_SERVER_OK: case COSMS_CORE_SERVER_OK:
return "cosms-core-server everything ok"; return "cosms-core-server everything ok";