diff --git a/CMakeLists.txt b/CMakeLists.txt index bd6b4d2..f5f2560 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,10 @@ file(GLOB_RECURSE SRC_FILES "${PROJECT_SOURCE_DIR}/src/*.c") add_library(cosms-core STATIC ${SRC_FILES}) target_include_directories(cosms-core PUBLIC ${PROJECT_SOURCE_DIR}/include) +if (WIN32) + target_link_libraries(cosms-core PRIVATE ws2_32) +endif() + if (MSVC) target_compile_options(cosms-core PRIVATE /W4) else() diff --git a/include/cosms-core/networking/server.h b/include/cosms-core/networking/server.h index bf2ed91..718f271 100644 --- a/include/cosms-core/networking/server.h +++ b/include/cosms-core/networking/server.h @@ -16,7 +16,7 @@ #elif defined(_WIN32) #include -#define COSMS_CORE_SERVER_INVALID_SOCKET (SOCKET)(0) +#define COSMS_CORE_SERVER_INVALID_SOCKET INVALID_SOCKET #endif typedef enum { @@ -79,14 +79,7 @@ CosmsCoreServerError cosms_core_server_destroy(struct cosms_core_server *current * @param backlog How many clients will be put in the backlog before connections are declined * @return COSMS_CORE_SERVER_OK on success, or negative error code */ -inline CosmsCoreServerError cosms_core_server_listen(struct cosms_core_server *current_server, unsigned int backlog) { - int result = listen(current_server->listening_socket, backlog); - if (result == -1) { - return COSMS_CORE_SERVER_COULD_NOT_SET_MODE; - } - - return COSMS_CORE_SERVER_OK; -} +CosmsCoreServerError cosms_core_server_listen(struct cosms_core_server *current_server, unsigned int backlog); /** * @brief Accepts incomming connection (tcp only) * @@ -94,14 +87,7 @@ inline CosmsCoreServerError cosms_core_server_listen(struct cosms_core_server *c * @param client Pointer to client struct to store the connected client in * @return COSMS_CORE_SERVER_OK on success, or negative error code */ -inline CosmsCoreServerError cosms_core_server_accept(struct cosms_core_server *current_server, struct cosms_core_server_client *client) { - client->socket = accept(current_server->listening_socket, (struct sockaddr*)&client->address, &client->address_length); - if (client->socket == COSMS_CORE_SERVER_INVALID_SOCKET) { - return COSMS_CORE_SERVER_FAILED_TO_ACCEPT; - } - - return COSMS_CORE_SERVER_OK; -} +CosmsCoreServerError cosms_core_server_accept(struct cosms_core_server *current_server, struct cosms_core_server_client *client); /** * @brief Receives message from client. diff --git a/src/networking/server.c b/src/networking/server.c index 20d671c..f126218 100644 --- a/src/networking/server.c +++ b/src/networking/server.c @@ -30,7 +30,7 @@ CosmsCoreServerError cosms_core_server_create(struct cosms_core_server *new_serv #if defined(_WIN32) if (cosms_core_server_initialized_winsock_instances == 0) { WSADATA data; - if (WSAStartup(MAKEWORD(2, 2), &data) == 0) { + if (WSAStartup(MAKEWORD(2, 2), &data) != 0) { return COSMS_CORE_SERVER_FAILED_TO_CREATE_SOCKET; } } @@ -48,6 +48,12 @@ CosmsCoreServerError cosms_core_server_create(struct cosms_core_server *new_serv return COSMS_CORE_SERVER_COULD_NOT_BIND_ADDRESS; } + if (port == 0) { + int address_length = sizeof(address); + getsockname(new_server->listening_socket, (struct sockaddr*)&address, &address_length); + new_server->port = ntohs(address.sin_port); + } + return COSMS_CORE_SERVER_OK; } @@ -75,6 +81,30 @@ CosmsCoreServerError cosms_core_server_destroy(struct cosms_core_server *current return COSMS_CORE_SERVER_OK; } +/** + * @brief Sets server in listening state so it can listen for incomming connections (tcp only). + */ +CosmsCoreServerError cosms_core_server_listen(struct cosms_core_server *current_server, unsigned int backlog) { + int result = listen(current_server->listening_socket, backlog); + if (result == -1) { + return COSMS_CORE_SERVER_COULD_NOT_SET_MODE; + } + + return COSMS_CORE_SERVER_OK; +} + +/** + * @brief Accepts incomming connection (tcp only). + */ +CosmsCoreServerError cosms_core_server_accept(struct cosms_core_server *current_server, struct cosms_core_server_client *client) { + client->socket = accept(current_server->listening_socket, (struct sockaddr*)&client->address, &client->address_length); + if (client->socket == COSMS_CORE_SERVER_INVALID_SOCKET) { + return COSMS_CORE_SERVER_FAILED_TO_ACCEPT; + } + + return COSMS_CORE_SERVER_OK; +} + /** * @brief Receives message from client. */ diff --git a/tests/unit/networking/server.c b/tests/unit/networking/server.c new file mode 100644 index 0000000..a3f0e1a --- /dev/null +++ b/tests/unit/networking/server.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) Tristan Franssen, . + * + * 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 "unit/networking/server.h" + +#include +#include + +COSMS_CORE_TEST_TEST(server_create_tcp_server, + struct cosms_core_server tcp_server; + CosmsCoreServerError error = cosms_core_server_create(&tcp_server, AF_INET, SOCK_STREAM, 0); + if (error != COSMS_CORE_SERVER_OK) { + return cosms_core_server_error_string(error); + } + + error = cosms_core_server_destroy(&tcp_server); + if (error != COSMS_CORE_SERVER_OK) { + return cosms_core_server_error_string(error); + } + + return NULL; +) + +COSMS_CORE_TEST_TEST(server_create_udp_server, + struct cosms_core_server udp_server; + CosmsCoreServerError error = cosms_core_server_create(&udp_server, AF_INET, SOCK_DGRAM, 0); + if (error != COSMS_CORE_SERVER_OK) { + return cosms_core_server_error_string(error); + } + + error = cosms_core_server_destroy(&udp_server); + if (error != COSMS_CORE_SERVER_OK) { + return cosms_core_server_error_string(error); + } + + return NULL; +) + +COSMS_CORE_TEST_TEST(server_listen_on_tcp_server, + struct cosms_core_server tcp_server; + CosmsCoreServerError error = cosms_core_server_create(&tcp_server, AF_INET, SOCK_STREAM, 0); + if (error != COSMS_CORE_SERVER_OK) { + return cosms_core_server_error_string(error); + } + + error = cosms_core_server_listen(&tcp_server, 10); + if (error != COSMS_CORE_SERVER_OK) { + return cosms_core_server_error_string(error); + } + + error = cosms_core_server_destroy(&tcp_server); + if (error != COSMS_CORE_SERVER_OK) { + return cosms_core_server_error_string(error); + } + + return NULL; +) + +COSMS_CORE_TEST_TEST(server_listen_on_udp_server, + struct cosms_core_server udp_server; + CosmsCoreServerError error = cosms_core_server_create(&udp_server, AF_INET, SOCK_DGRAM, 0); + if (error != COSMS_CORE_SERVER_OK) { + return cosms_core_server_error_string(error); + } + + error = cosms_core_server_listen(&udp_server, 10); + if (error != COSMS_CORE_SERVER_COULD_NOT_SET_MODE) { + return cosms_core_server_error_string(error); + } + + error = cosms_core_server_destroy(&udp_server); + if (error != COSMS_CORE_SERVER_OK) { + return cosms_core_server_error_string(error); + } + + return NULL; +) \ No newline at end of file diff --git a/tests/unit/networking/server.h b/tests/unit/networking/server.h new file mode 100644 index 0000000..d581af2 --- /dev/null +++ b/tests/unit/networking/server.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) Tristan Franssen, . + * + * 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_TEST +#define COSMS_CORE_SERVER_TEST + +#include "test.h" + +COSMS_CORE_TEST_DEFINE(server_create_tcp_server); +COSMS_CORE_TEST_DEFINE(server_create_udp_server); +COSMS_CORE_TEST_DEFINE(server_listen_on_tcp_server); +COSMS_CORE_TEST_DEFINE(server_listen_on_udp_server); + +COSMS_CORE_TEST_EXPORT(server, + COSMS_CORE_TEST_EXPORT_TEST(server_create_tcp_server), + COSMS_CORE_TEST_EXPORT_TEST(server_create_udp_server), + COSMS_CORE_TEST_EXPORT_TEST(server_listen_on_tcp_server), + COSMS_CORE_TEST_EXPORT_TEST(server_listen_on_udp_server) +); + +#endif /* COSMS_CORE_SERVER_TEST */ \ No newline at end of file diff --git a/tests/unit/unit.h b/tests/unit/unit.h index fbd3a3e..e1af003 100644 --- a/tests/unit/unit.h +++ b/tests/unit/unit.h @@ -11,9 +11,11 @@ #include "test.h" #include "file.h" +#include "networking/server.h" COSMS_CORE_TEST_START - COSMS_CORE_TEST_IMPORT(file) + COSMS_CORE_TEST_IMPORT(file), + COSMS_CORE_TEST_IMPORT(server) COSMS_CORE_TEST_END #endif \ No newline at end of file