feat(server): added receive function for udp and tcp servers
This commit is contained in:
parent
fe7fea1c94
commit
8c4cf93f33
2 changed files with 60 additions and 14 deletions
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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";
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue