Implemented dynamic list! Needs some testing.

This commit is contained in:
Max 2022-12-14 20:14:54 +01:00
parent f84629ca42
commit 3069cc0d2f
11 changed files with 165 additions and 41 deletions

View File

@ -1,6 +1,7 @@
add_executable(cexp
"main.c"
"sockets.h")
"exp_list.c")
target_include_directories(cexp PRIVATE ${CMAKE_SOURCE_DIR}/src/include)
add_subdirectory(include)
add_subdirectory(sockets)

64
src/exp_list.c Normal file
View File

@ -0,0 +1,64 @@
#include "stdlib.h"
#include "cexp.h"
#define INCREMENT_SIZE 5
int alloc_list();
int increment_list();
static int list_index_count = 0;
static int list_index_total = 0;
static struct exp_data* list = NULL;
void list_add(char* name, char* command, int (*exp_func) (void*))
{
if (alloc_list() != 0)
{ TRACE_ERROR("Unable to allocate memory!"); return; }
list[list_index_count].name = name;
list[list_index_count].command = command;
list[list_index_count].func_ptr = exp_func;
list_index_count++;
}
int alloc_list()
{
if (list == NULL)
{
list = (struct exp_data*)calloc(sizeof(struct exp_data), INCREMENT_SIZE);
if (list == NULL)
return -1;
list_index_total += INCREMENT_SIZE;
}
if (list_index_total <= list_index_count)
return increment_list();
return 0;
}
int increment_list()
{
list_index_total += INCREMENT_SIZE;
list = realloc(list, list_index_total * sizeof(struct exp_data));
if (list == NULL)
return -1;
return 0;
}
void print_list_items()
{
for (int i = 0; i < list_index_count; i++)
{
PRINT_LINE("%i. %s", i, list[i].name);
}
}
struct exp_data* get_from_list(int index)
{
if (index > list_index_count)
return NULL;
return &list[index];
}
void clear_list()
{
if (list != NULL)
free(list);
return;
}

View File

@ -0,0 +1,4 @@
target_sources(cexp PUBLIC
"cexp.h"
"sockets.h")

23
src/include/cexp.h Normal file
View File

@ -0,0 +1,23 @@
#ifndef CEXP_H
#define CEXP_H
#include <stdio.h>
#include <ctype.h>
struct exp_data{
char* name;
char* command;
int (*func_ptr) (void*);
};
// Exp list functions
void list_add(char* name, char* command, int (*exp_func) (void*));
void print_list_items();
struct exp_data* get_from_list(int index);
void clear_list();
// Tracing
#define PRINT_LINE(msg, args...) fprintf(stdout, #msg "\n", ##args)
#define TRACE_WARN(msg, args...) fprintf(stdout, "[Warning]: " #msg "\n", ##args)
#define TRACE_ERROR(msg, args...) fprintf(stderr, "[ERROR]: " #msg "\n", ##args)
#endif

View File

@ -12,9 +12,8 @@ struct net_data
char sName[100];
};
void clientstart();
int clientstart();
int start_server();
int stop_server();
int writeToSock(int fd, void* data, ssize_t size);

View File

@ -3,14 +3,26 @@
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include "cexp.h"
#include "sockets.h"
int checkarg(int argc, char* argv[]);
int handleoptions();
static void sig_handler();
int main(int argc, char *argv[])
{
list_add("Socket server", "sock:server", start_server);
list_add("Socket client", "sock:client", clientstart);
printf(" _____ \n / ____| \n | | _____ ___ __ \n | | / _ \\ \\/ / '_ \\ \n | |___| __/> <| |_) |\n \\_____\\___/_/\\_\\ .__/ \n | | \n |_| \n");
signal(SIGINT, sig_handler);
int argresult = checkarg(argc, argv);
if (argresult == 0) // If checkarg returns 0 that means it succesfully handled the argruments.
return argresult;
return handleoptions(); // If the app does not get args we will display a small options menu.
}
int checkarg(int argc, char* argv[])
{
if (argc == 2)
{
if (strcmp(argv[1], "server") == 0)
@ -23,14 +35,35 @@ int main(int argc, char *argv[])
return 0;
}
}
return -1;
}
printf("None or too much arguments passed!\n");
return 0;
int handleoptions()
{
PRINT_LINE("Choose a option:");
print_list_items();
int index;
if (scanf("%d", &index) == 0)
{
TRACE_WARN("No valid option selected!");
return -1;
}
struct exp_data* data = get_from_list(index);
if (data == NULL)
{
TRACE_ERROR("Could not get required data from list!");
return -1;
}
PRINT_LINE("Option: %s choosen", data->name);
return data->func_ptr != NULL ? data->func_ptr(NULL) : -1;
}
// Handle the signal to exit the app!
static void sig_handler()
{
stop_server();
clear_list(); // Clear the exp list.
exit(0);
}

View File

@ -5,10 +5,11 @@
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "../sockets.h"
#include "cexp.h"
#include "sockets.h"
void clientstart()
int clientstart()
{
int client_sockfd = socket(AF_INET, SOCK_STREAM, 0);
@ -20,34 +21,34 @@ void clientstart()
int connection_status = connect(client_sockfd, (struct sockaddr*) &client_sockaddr, sizeof(client_sockaddr));
if (connection_status != 0)
{
printf("ERROR: Could not connect!\n");
return;
TRACE_ERROR("Could not connect!");
return -1;
}
ssize_t nextRecSize = 0;
ssize_t recvRead = readFromSock(client_sockfd, &nextRecSize, sizeof(uint32_t));
if (recvRead == -1)
{
printf("ERROR: Failed to receive data!\nErrno: %i", errno);
return;
TRACE_ERROR("Failed to receive data! Errno: %i", errno);
return -1;
}
nextRecSize = ntohl(nextRecSize);
char serverName[64];
recvRead = readFromSock(client_sockfd, &serverName, nextRecSize);
if (recvRead == -1)
return;
return -1;
if (recvRead == 0)
{
printf("No data received!\n");
PRINT_LINE("No data received!");
}
printf("Connected with: %s\n", serverName);
PRINT_LINE("Connected with: %s", serverName);
for (;;)
{
char c = getchar();
if (c == 'q')
return;
return 0;
}
}

View File

@ -3,7 +3,8 @@
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "../sockets.h"
#include "cexp.h"
#include "sockets.h"
#include "thread_manager.h"
int server_sockfd;
@ -16,11 +17,11 @@ void* thread_client_handler(void* arg);
int start_server()
{
printf(" _____ \n / ____| \n | | _____ ___ __ \n | | / _ \ \/ / '_ \ \n | |___| __/> <| |_) |\n \_____\___/_/\_\ .__/ \n | | \n |_| \n");
PRINT_LINE("Starting socket server...");
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (server_sockfd < 0)
{
printf("ERROR: Could not create server socket!\n");
TRACE_ERROR("Could not create server socket!");
return -1;
}
@ -31,34 +32,30 @@ int start_server()
int bind_result = bind(server_sockfd, (struct sockaddr *) &server_sockaddr, sizeof(server_sockaddr));
if (bind_result != 0)
{
printf("ERROR: Cannot bind to socket!\n");
TRACE_ERROR("Cannot bind to socket!");
return -1;
}
while (b_listen)
{
printf("Waiting for a connection...\n");
PRINT_LINE("Waiting for a connection...");
int listen_result = listen(server_sockfd, 1);
if (listen_result == -1)
{
printf("ERROR: Could not listen. code: %i", errno);
TRACE_ERROR("Could not listen. code: %i", errno);
return -1;
}
int clientfd = accept(server_sockfd, NULL, NULL);
if (clientfd == -1)
{
printf("ERROR: Could not accept client!");
TRACE_ERROR("Could not accept client!");
continue;
}
if (init_thread(&clientfd, thread_client_handler) == -1)
printf("Warning: Could not establish connection with client!");
TRACE_WARN("Could not establish connection with client!");
}
return 0;
}
int stop_server()
{
return 0;
}
// Function used in thread to handle the connected client.
//TODO: Return a type with status, with message on why a value is returned.
@ -67,7 +64,7 @@ void* thread_client_handler(void* arg)
int client_fd = *(int*)arg;
// Send data size to client.
ssize_t sNameSize = sizeof(sName);
ssize_t sNameSize = strlen(sName);
uint32_t sDataSize = htonl(sNameSize);
int sendResult = writeToSock(client_fd, &sDataSize, sizeof(uint32_t));
if (sendResult == -1)// If we are not be able to send data, return so the thread can exit.
@ -82,24 +79,24 @@ void* thread_client_handler(void* arg)
// Wait for command data from client.
for(;;)
{
printf("Listening to client for data!\n");
PRINT_LINE("Listening to client for data...");
int rec_result;
rec_result = recv(client_fd, buff, sizeof(buff), 0);
if (rec_result == -1)
{
printf("Warning: could not recieve data from client!\n");
TRACE_WARN("Could not recieve data from client!");
continue;
}
if (rec_result == 0)
{
printf("Client disconnected!\n");
PRINT_LINE("Client disconnected!");
break;
}
}
int close_result = close(client_fd);
printf("Close network result: %i\n", close_result);
PRINT_LINE("Close network result: %i", close_result);
return NULL;
}

View File

@ -1,4 +1,5 @@
#include "../sockets.h"
#include "cexp.h"
#include "sockets.h"
int writeToSock(int fd, void* data, ssize_t size)
{
@ -9,7 +10,7 @@ int writeToSock(int fd, void* data, ssize_t size)
dataSizeSend += send(fd, (char*)data + dataSizeSend, size - dataSizeSend, 0);
if (dataSizeSend == -1)
{
printf("Warning: Cannot send data!\n");
TRACE_WARN("Cannot send data!");
return -1;
}
}
@ -26,7 +27,7 @@ int readFromSock(int fd, void* buff, ssize_t size)
dataRecv += recv(fd, (char*)buff + dataRecv, size - dataRecv, 0);
if (dataRecv == -1)
{
printf("Warning: Cannot receive data!\n");
TRACE_WARN("Cannot receive data!");
return -1;
}
}

View File

@ -1,4 +1,5 @@
#include <stdio.h>
#include "cexp.h"
#include "thread_manager.h"
int init_thread(int* clientfd, void *(*func) (void *))
@ -7,10 +8,10 @@ int init_thread(int* clientfd, void *(*func) (void *))
int thread_create_result = pthread_create(&thread, NULL, func, clientfd);
if (thread_create_result == -1)
{
printf("ERROR: Could not create thread!\n");
TRACE_ERROR("Could not create thread!");
return thread_create_result;
}
printf("Init thread: %lu\n", thread);
PRINT_LINE("Init thread: %lu", thread);
return 0;
}

View File

@ -1,7 +1,7 @@
#ifndef THREAD_MANAGER_H
#define THREAD_MANAGER_H
#include <pthread.h>
#include "../sockets.h"
#include "sockets.h"
int init_thread(int* clientfd, void *(*func) (void *));