diff --git a/CMakeLists.txt b/CMakeLists.txt index d821127..ea7bae9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,5 +5,19 @@ execute_process( COMMAND mkdir -p bin ) -add_executable(./bin/server ./src/server.c) -add_executable(./bin/client ./src/client.c) +set(SOURCE_FILES + src/socket.c + src/pipe.c + src/utils.c +) + +set(CMAKE_CXX_STANDARD 11) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") + +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -march=native") + +include_directories(include) + +add_executable(./bin/server ${SOURCE_FILES} ./src/main_server.c) +add_executable(./bin/client ${SOURCE_FILES} ./src/main_client.c) diff --git a/bin/client b/bin/client index 6454ae7..3232dcf 100755 Binary files a/bin/client and b/bin/client differ diff --git a/bin/server b/bin/server index d23a0f2..14f5cff 100755 Binary files a/bin/server and b/bin/server differ diff --git a/data/graphic_with_bloxplot.py b/data/graphic_with_bloxplot.py new file mode 100644 index 0000000..2622952 --- /dev/null +++ b/data/graphic_with_bloxplot.py @@ -0,0 +1,34 @@ +import matplotlib.pyplot as plt +import numpy as np + +# Lista de valores para os eixos x e y +tamanho_buffer = ["0.064", "0.128", "0.256", "0.512", "1", "2", "4", "8"] +tempo_execucao_udp = [0.28, 0.24, 0.19, 0.17, 0.15, 0.14, 0.12, 0.09] +tempo_execucao_tcp = [0.40, 0.23, 0.20, 0.18, 0.17, 0.16, 0.16, 0.13] +tempo_execucao_unix = [0.22, 0.19, 0.19, 0.12, 0.15, 0.10, 0.08, 0.05] + +tempo_execucao_udp.reverse() +tempo_execucao_tcp.reverse() +tempo_execucao_unix.reverse() + +# Cria o gráfico de linha +plt.plot(tamanho_buffer, tempo_execucao_tcp, marker='o', linestyle='-', label='Socket TCP') +plt.plot(tamanho_buffer, tempo_execucao_unix, marker='o', linestyle='-', label='Socket UNIXDOMAIN') +plt.plot(tamanho_buffer, tempo_execucao_udp, marker='o', linestyle='-', label='Socket UDP') + +# Box plots +plt.boxplot([tempo_execucao_tcp, tempo_execucao_unix, tempo_execucao_udp], labels=['TCP', 'UNIXDOMAIN', 'UDP']) + +plt.yscale('log') +ticks_y = [0.01, 0.1, 1, 10] +plt.yticks(ticks_y, [f'$10^{{{int(np.log10(val))}}}$' for val in ticks_y]) + +plt.xlabel('Tamanho do buffer em (KB)') +plt.ylabel('Tempo de execução em (ms)') +plt.title('Desempenho de conexões UDP, TCP e UNIXDOMAIN') + +plt.grid(axis='y', linestyle='--', alpha=0.7) + +plt.legend() + +plt.show() diff --git a/data/main.py b/data/main.py index b9797ff..44110b5 100644 --- a/data/main.py +++ b/data/main.py @@ -1,11 +1,30 @@ -import pylab import matplotlib.pyplot as plt -a = [pow(10, i) for i in range(10)] -fig = plt.figure() -ax = fig.add_subplot(2, 1, 1) +import numpy as np -line, = ax.plot(a, color='blue', lw=2) +# Lista de valores para os eixos x e y +tamanho_buffer = ["0.064", "0.128", "0.256", "0.512", "1", "2", "4", "8"] +tempo_execucao_udp = [0.28, 0.24, 0.19, 0.17, 0.15, 0.14, 0.12, 0.09] +tempo_execucao_tcp = [0.40,0.23,0.20,0.18,0.17,0.16,0.16,0.13] +tempo_execucao_unix = [0.22,0.19,0.19,0.12,0.15,0.10,0.08,0.05] -ax.set_yscale('log') +tempo_execucao_udp.reverse() +tempo_execucao_tcp.reverse() +tempo_execucao_unix.reverse() -pylab.show() +# Cria o gráfico de linha +plt.plot(tamanho_buffer, tempo_execucao_tcp, marker='o', linestyle='-', label='Socket TCP') +plt.plot(tamanho_buffer, tempo_execucao_unix, marker='o', linestyle='-', label='Socket UNIXDOMAIN') +plt.plot(tamanho_buffer, tempo_execucao_udp, marker='o', linestyle='-', label='Socket UDP') + +plt.yscale('log') +plt.legend() +ticks_y = [0.01, 0.1,1,10] +plt.yticks(ticks_y, [f'$10^{{{int(np.log10(val))}}}$' for val in ticks_y]) + +plt.xlabel('Tamanho do buffer em (KB)') +plt.ylabel('Tempo de execução em (ms)') +plt.title('Desempenho de conexões UDP, TCP e UNIXDOMAIN') + +plt.grid(axis='y', linestyle='--', alpha=0.7) + +plt.show() diff --git a/graphics/full.png b/graphics/full.png new file mode 100644 index 0000000..05c3643 Binary files /dev/null and b/graphics/full.png differ diff --git a/graphics/full_box_plot.png b/graphics/full_box_plot.png new file mode 100644 index 0000000..7bfce6a Binary files /dev/null and b/graphics/full_box_plot.png differ diff --git a/graphics/tcp.png b/graphics/tcp.png new file mode 100644 index 0000000..5df077e Binary files /dev/null and b/graphics/tcp.png differ diff --git a/graphics/udp.png b/graphics/udp.png new file mode 100644 index 0000000..69d88ff Binary files /dev/null and b/graphics/udp.png differ diff --git a/include/pipe.h b/include/pipe.h new file mode 100644 index 0000000..c4a04b4 --- /dev/null +++ b/include/pipe.h @@ -0,0 +1,14 @@ +#ifndef __PIPE_H__ + + #define PIPE_ERROR_CODE -1 + #define PROCESS_ERROR_CODE -1 + #define NUM_OF_PIPE_DESCRIPTORS 2 + #define CHILD_PROCESS 0 + + #include + + extern int *create_pipe(); + extern pid_t fork_process(); + + extern float pingpong_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer); +#endif // __PIPE_H__ \ No newline at end of file diff --git a/include/socket.h b/include/socket.h new file mode 100644 index 0000000..a12e954 --- /dev/null +++ b/include/socket.h @@ -0,0 +1,27 @@ +#ifndef __SOCKET_H__ + + #define SOCKET_ERROR_CODE -1 // Socket create, Connection server, Receive buffer to server code error + #define SYSTEM_EXIT_FAILED 1 // Operating System program error response + #define HOST_IP "127.0.0.1" // IPV4 loopback address + #define SERVER_PORT 8481 // Server port + #define UNIXDOAMIN_ADDRESS "pingpong.socket" + #define MAX_CONNECTIONS 1 // Num max client connected simultaneously + + #define NUM_OF_ARGUMENTS 3 + #define TCP_SOCKET_FLAG 1 + #define UDP_SOCKET_FLAG 2 + #define UNIX_SOCKET_FLAG 3 + #define PIPE_CONNECTION_FLAG 4 + + typedef struct sockaddr_in socket_address_ipv4; + typedef struct sockaddr_un socket_address_unix; + typedef struct sockaddr_in socket_address; + + extern int create_socket(int sin_family, int sock); + extern socket_address_unix config_unixdomain_server_address(); + extern socket_address_ipv4 config_tcp_upd_server_address(); + extern void connect_to_server(void* server_address, int client_socket); + extern void bind_server(void* server_address, int socket_type, int server_socket); + extern int accept_connection(int client_socket, void* client_address, int server_socket); + +#endif // __SOCKET_H__ \ No newline at end of file diff --git a/include/utils.h b/include/utils.h new file mode 100644 index 0000000..442e285 --- /dev/null +++ b/include/utils.h @@ -0,0 +1,21 @@ +#ifndef __UTILS_H__ + + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #define SYSTEM_EXIT_SUCCESS 0 // Operating System program success response + #define SYSTEM_EXIT_FAILURE 1 // Operating System program error response + #define TRUE 1 + #define FALSE 0 + + extern void panic(char* message); + extern int* get_init_buffer(int buffer_size); + +#endif // __UTILS_H__ \ No newline at end of file diff --git a/src/client.c b/src/client.c deleted file mode 100644 index c9eff84..0000000 --- a/src/client.c +++ /dev/null @@ -1,231 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define N 10000 -#define TRUE 1 -#define FALSE 0 -#define HOST_IP "127.0.0.1" // IPV4 loopback address -#define SERVER_PORT 8481 // Server port -#define PORT_USED_CODE 256 -#define SOCKET_ERROR_CODE -1 // Socket create, Connection server, Receive buffer to server code error -#define SYSTEM_EXIT_FAILED 1 // Operating System program error response -#define SYSTEM_EXIT_SUCCESS 0 // Operating System program success response -#define NUM_OF_ARGUMENTS 3 -#define TCP_SOCKET_FLAG 1 -#define UDP_SOCKET_FLAG 2 -#define UNIX_SOCKET_FLAG 3 - -float times[N]; - -int num_of_read_bytes = 0; - -typedef struct sockaddr_in socket_address_ipv4; -typedef struct sockaddr_un socket_address_unix; - -typedef union socketaddr_t -{ - socket_address_ipv4 socket_ipv4; - socket_address_unix socket_unix; - -} socketaddr_t; - - -socketaddr_t server_address; - -size_t buffer_size; -int socket_type; - -int domain, type, protocol; - -float elapsed_time_ms = 0.00; - -char* address; -int domain, type, protocol, sin_family, sock; - -typedef struct sockaddr_in socket_address; - -void panic(char* message) -{ - perror(message); - exit(SYSTEM_EXIT_FAILED); -} - -int init_socket() -{ - int client_socket = socket(sin_family, sock, -1); - - if(client_socket == SOCKET_ERROR_CODE) - { - panic("Socket create failed!\n"); - } - - return client_socket; -} - -socketaddr_t config_server_address() -{ - - if(socket_type == UNIX_SOCKET_FLAG) - { - server_address.socket_ipv4.sin_family = sin_family; - server_address.socket_ipv4.sin_port = htons(SERVER_PORT); - server_address.socket_ipv4.sin_addr.s_addr = inet_addr(address); - - - }else{ - - server_address.socket_unix.sun_family = AF_UNIX; - strcpy(server_address.socket_unix.sun_path, address); - unlink(address); - } -} - -void connect_to_server(int client_socket) - -{ - struct sockaddr* address = socket_type == UNIX_SOCKET_FLAG ? (struct sockaddr*)&server_address.socket_unix : (struct sockaddr*)&server_address.socket_ipv4; - - int connection_response = connect(client_socket, - address, - socket_type == UNIX_SOCKET_FLAG ? (socklen_t)sizeof(server_address.socket_unix) : (socklen_t)sizeof(server_address.socket_ipv4) - ); - - if(connection_response == SOCKET_ERROR_CODE) - { - - close(client_socket); - panic("Server connection error\n"); - } -} - -int receive_buffer(int client_socket, int buffer_size) -{ - int received_buffer[buffer_size]; - - if(socket_type == TCP_SOCKET_FLAG) recv(client_socket, received_buffer, buffer_size, 0); - else - { - struct sockaddr* address = socket_type == UNIX_SOCKET_FLAG ? (struct sockaddr*)&server_address.socket_unix : (struct sockaddr*)&server_address.socket_ipv4; - socklen_t* server_addr_size = socket_type == UNIX_SOCKET_FLAG ? (socklen_t*)sizeof(server_address.socket_unix) : (socklen_t*)sizeof(server_address.socket_ipv4); - recvfrom(client_socket, received_buffer, buffer_size, 0, address, server_addr_size); - } -} - -void send_buffer(int client_socket, int* buffer, size_t buffer_size) -{ - - struct sockaddr* address = socket_type == UNIX_SOCKET_FLAG ? (struct sockaddr*)&server_address.socket_unix : (struct sockaddr*)&server_address.socket_ipv4; - socklen_t server_addr_size = socket_type == UNIX_SOCKET_FLAG ? (socklen_t)sizeof(server_address.socket_unix) : (socklen_t)sizeof(server_address.socket_ipv4); - - if(socket_type == TCP_SOCKET_FLAG) send(client_socket, buffer, buffer_size, 0); - else sendto(client_socket, buffer, buffer_size, 0, address, server_addr_size); - - receive_buffer(client_socket, buffer_size); -} - -void controlc_handler() -{ - printf("\nProgram finished!\n"); - exit(SYSTEM_EXIT_SUCCESS); -} - -void socket_listen(int client_socket, int* buffer, size_t buffer_size) -{ - - if(signal(SIGINT, controlc_handler) == SIG_ERR) - { - panic("Signal create error!"); - } - - clock_t start_time = clock(); - send_buffer(client_socket, buffer, buffer_size); - clock_t end_time = clock(); - - elapsed_time_ms = ((float)(end_time - start_time) / (CLOCKS_PER_SEC/1000)); -} - - -void attribuite_socket_type(int socket_type) -{ - switch (socket_type) - { - case TCP_SOCKET_FLAG: // TCP SOCKET - - sin_family = AF_INET; - address = HOST_IP; - sock = SOCK_STREAM; - - break; - - case UDP_SOCKET_FLAG: // UDP SOCKET - - sin_family = AF_INET; - address = HOST_IP; - sock = SOCK_DGRAM; - - break; - - case UNIX_SOCKET_FLAG: // UNIXDOMAIN SOCKET - - sin_family = AF_UNIX; - address = "pingpong.socket";; - sock = SOCK_DGRAM; - - break; - - default: - panic("Value error!"); - break; - } -} - -void get_args(int argc, char** argv) -{ - if(argc > NUM_OF_ARGUMENTS) - { - buffer_size = (int)atoi(argv[1]); - num_of_read_bytes = (int)atoi(argv[2]); - socket_type = (int)atoi(argv[3]); - }else - { - panic("Argument is missing!"); - } - -} - -int main(int argc, char** argv) -{ - - get_args(argc, argv); - attribuite_socket_type(socket_type); - - int* buffer = (int*)malloc(buffer_size*sizeof(int)); - - - for(int i = 0; i < buffer_size; i++) - { - buffer[i] = (int)(i % 255); - } - - int client_socket = init_socket(); - - server_address = config_server_address(); - - connect_to_server(client_socket); - - for(int i = 0; i < num_of_read_bytes; i++) - { - socket_listen(client_socket, buffer, buffer_size); - - printf("%lf\n", (float)(elapsed_time_ms)); - } - - return SYSTEM_EXIT_SUCCESS; -} diff --git a/src/main b/src/main new file mode 100755 index 0000000..6f3487a Binary files /dev/null and b/src/main differ diff --git a/src/main_client.c b/src/main_client.c new file mode 100644 index 0000000..ecb2e1d --- /dev/null +++ b/src/main_client.c @@ -0,0 +1,142 @@ +#include "../include/socket.h" +#include "../include/pipe.h" +#include "../include/utils.h" + +#define N 10000 + +float times[N]; + +int num_of_read_bytes = 0; + +int client_socket; +int* buffer; +size_t buffer_size; +int socket_type; + +pid_t child; +int *descriptors; + +void* server_address; + +float elapsed_time_ms = 0.00; + +int receive_buffer(void *server_address) +{ + int received_buffer[buffer_size]; + + if(socket_type == TCP_SOCKET_FLAG) recv(client_socket, received_buffer, buffer_size, 0); + else + { + struct sockaddr* address = (struct sockaddr*)&server_address; + socklen_t* server_addr_size = (socklen_t*)sizeof(server_address); + recvfrom(client_socket, received_buffer, buffer_size, 0, address, server_addr_size); + } +} + +void send_buffer(void *server_address) +{ + + struct sockaddr* address = (struct sockaddr*)&server_address; + socklen_t server_addr_size = (socklen_t)sizeof(server_address); + + if(socket_type == TCP_SOCKET_FLAG) send(client_socket, buffer, buffer_size, 0); + else sendto(client_socket, buffer, buffer_size, 0, address, server_addr_size); + receive_buffer(server_address); +} + +void controlc_handler() +{ + printf("\nProgram finished!\n"); + exit(SYSTEM_EXIT_SUCCESS); +} + +void socket_listen() +{ + + if(signal(SIGINT, controlc_handler) == SIG_ERR) + { + panic("Signal create error!"); + } + + clock_t start_time = clock(); + send_buffer(server_address); + clock_t end_time = clock(); + + elapsed_time_ms = ((float)(end_time - start_time) / (CLOCKS_PER_SEC/1000)); +} + +void attribuite_and_init_socket(int socket_type) +{ + switch (socket_type) + { + case TCP_SOCKET_FLAG: // TCP SOCKET + client_socket = create_socket(AF_INET, SOCK_STREAM); + socket_address_ipv4 tcp_ip_address = config_tcp_upd_server_address(); + server_address = (void*)&tcp_ip_address; + connect_to_server(server_address,client_socket); + break; + + case UDP_SOCKET_FLAG: // UDP SOCKET + client_socket = create_socket(AF_INET, SOCK_STREAM); + socket_address_ipv4 udp_ip_address = config_tcp_upd_server_address(); + server_address = (void*)&udp_ip_address; + connect_to_server(server_address,client_socket); + + break; + + case UNIX_SOCKET_FLAG: // UNIXDOMAIN SOCKET + client_socket = create_socket(AF_UNIX, SOCK_DGRAM); + socket_address_unix unix_ip_address = config_unixdomain_server_address(); + server_address = (void*)&unix_ip_address; + connect_to_server(server_address,client_socket); + + break; + + case PIPE_CONNECTION_FLAG: // PIPE CONNECTION FLAG + + descriptors = create_pipe(); + child = fork_process(); + + break; + + default: + panic("Value error!"); + break; + } +} + + +void get_args(int argc, char** argv) +{ + if(argc > NUM_OF_ARGUMENTS) + { + buffer_size = (int)atoi(argv[1]); + num_of_read_bytes = (int)atoi(argv[2]); + socket_type = (int)atoi(argv[3]); + }else + { + panic("Argument is missing!"); + } +} + +int main(int argc, char** argv) +{ + + get_args(argc, argv); + attribuite_and_init_socket(socket_type); + + buffer = get_init_buffer(buffer_size); + + float sum_elapsed_time_ms = 0.0; + + for(int i = 0; i < num_of_read_bytes; i++) + { + socket_type == PIPE_CONNECTION_FLAG ? elapsed_time_ms = pingpong_pipe(descriptors, child, buffer_size, buffer) : socket_listen(); + + sum_elapsed_time_ms += elapsed_time_ms; + } + + printf("%lf\n", (float)((sum_elapsed_time_ms)/(num_of_read_bytes))); + + return SYSTEM_EXIT_SUCCESS; +} diff --git a/src/main_server.c b/src/main_server.c new file mode 100644 index 0000000..c8e1662 --- /dev/null +++ b/src/main_server.c @@ -0,0 +1,134 @@ +#include "../include/socket.h" +#include "../include/pipe.h" +#include "../include/utils.h" + +int num_of_read_bytes = 0; + +socklen_t client_addr_len; + +int *descriptors; +pid_t child; + +int server_socket, client_socket; + + +socket_address client_address; + +void* server_address; + +int *buffer; +size_t buffer_size; +int socket_type; + +char* address; +int domain, type, protocol, sin_family, sock; + +void send_buffer(int* buffer) +{ + socklen_t client_addr_len = socket_type == sizeof(client_address); + struct sockaddr *address = (struct sockaddr*)&client_address; + + if(socket_type == TCP_SOCKET_FLAG) send(client_socket, buffer, buffer_size, 0); + else sendto(client_socket, buffer, buffer_size, 0, address, client_addr_len); +} + +int receive_buffer() +{ + ssize_t bytes_read; + + socklen_t* client_addr_len = (socklen_t *)sizeof(client_address); + struct sockaddr *address = (struct sockaddr*)&client_address; + int received_buffer[buffer_size]; + + while((bytes_read = socket_type == UNIX_SOCKET_FLAG ? recv(client_socket, received_buffer, buffer_size, 0) : recvfrom(client_socket, received_buffer, buffer_size, 0, address, client_addr_len)) > 0) + { + send_buffer(received_buffer); + } +} + +void controlc_handler() +{ + exit(SYSTEM_EXIT_SUCCESS); +} + +void server_listen() +{ + + if (listen(server_socket, MAX_CONNECTIONS) == SOCKET_ERROR_CODE) + { + + close(server_socket); + panic("Listening mode error"); + } + + client_socket = accept_connection(client_socket, (void*)&client_address, server_socket); + receive_buffer(); +} + +void attribuite_socket_type(int socket_type) +{ + switch (socket_type) + { + case TCP_SOCKET_FLAG: // TCP SOCKET + + server_socket = create_socket(AF_INET, SOCK_STREAM); + socket_address_ipv4 udp_ip_address = config_tcp_upd_server_address(); + server_address = (void *)&udp_ip_address; + break; + + case UDP_SOCKET_FLAG: // UDP SOCKET + + server_socket = create_socket(AF_INET, SOCK_DGRAM); + socket_address_ipv4 tcp_ip_address = config_tcp_upd_server_address(); + server_address = (void *)&tcp_ip_address; + break; + + case UNIX_SOCKET_FLAG: // UNIXDOMAIN SOCKET + server_socket = create_socket(AF_UNIX, SOCK_DGRAM); + socket_address_unix unix_address = config_unixdomain_server_address(); + server_address = (void *)&unix_address; + break; + + case PIPE_CONNECTION_FLAG: // PIPE CONNECTION FLAG + + descriptors = create_pipe(); + child = fork_process(); + + break; + + default: + panic("Value error!"); + break; + } +} + +void get_args(int argc, char** argv) +{ + if(argc > NUM_OF_ARGUMENTS) + { + buffer_size = (int)atoi(argv[1]); + num_of_read_bytes = (int)atoi(argv[2]); + socket_type = (int)atoi(argv[3]); + }else + { + panic("Argument is missing!"); + } + +} + +int main(int argc, char** argv) +{ + + get_args(argc, argv); + attribuite_socket_type(socket_type); + + buffer = (int*)malloc(buffer_size*sizeof(int)); + + bind_server(server_address, socket_type, server_socket); + + for(int i = 0; i < num_of_read_bytes; i++) + { + server_listen(); + } + return SYSTEM_EXIT_SUCCESS; +} diff --git a/src/pipe.c b/src/pipe.c new file mode 100644 index 0000000..8f19606 --- /dev/null +++ b/src/pipe.c @@ -0,0 +1,71 @@ +#include +#include + +#include "../include/pipe.h" +#include "../include/utils.h" + + +int *create_pipe() +{ + int *pipe_descriptors = (int*)malloc(NUM_OF_PIPE_DESCRIPTORS*sizeof(int)); + + if(pipe(pipe_descriptors) == PIPE_ERROR_CODE) + { + panic("Pipe creation failed"); + } + + return pipe_descriptors; +} + +pid_t fork_process() +{ + pid_t child_pid; + + if((child_pid == fork()) == PROCESS_ERROR_CODE) + { + panic("Fork failed"); + } + + return child_pid; +} + +float pingpong_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer) +{ + + int *pipe_client_to_server = create_pipe(); + int *pipe_server_to_client = create_pipe(); + + if (child == CHILD_PROCESS) + { + close(pipe_client_to_server[1]); + close(pipe_server_to_client[0]); + + ssize_t bytes_read; + clock_t start_time = clock(); + bytes_read = read(pipe_client_to_server[0], buffer, sizeof(buffer)); + + write(pipe_server_to_client[1], buffer, bytes_read); + clock_t end_time = clock(); + + close(pipe_client_to_server[0]); + close(pipe_server_to_client[1]); + + return ((float)(end_time - start_time) / (CLOCKS_PER_SEC/1000)); + }else + { + close(pipe_client_to_server[0]); + close(pipe_server_to_client[1]); + + clock_t start_time = clock(); + write(pipe_client_to_server[1], buffer, sizeof(buffer)); + + ssize_t bytes_read = read(pipe_server_to_client[0], buffer, sizeof(buffer)); + clock_t end_time = clock(); + + + close(pipe_client_to_server[1]); + close(pipe_server_to_client[0]); + + return ((float)(end_time - start_time) / (CLOCKS_PER_SEC/1000)); + } +} \ No newline at end of file diff --git a/src/server.c b/src/server.c deleted file mode 100644 index 63c27b6..0000000 --- a/src/server.c +++ /dev/null @@ -1,224 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#define FALSE 0 -#define TRUE 1 -#define HOST_IP "127.0.0.1" // IPV4 loopback address -#define SERVER_PORT 8481 // Server port -#define MAX_CONNECTIONS 1 // Num max client connected simultaneously -#define SOCKET_ERROR_CODE -1 // Socket create, Connection server, Receive buffer to server code error -#define SYSTEM_EXIT_FAILED 1 // Operating System program error response -#define SYSTEM_EXIT_SUCCESS 0 // Operating System program success response -#define NUM_OF_ARGUMENTS 3 -#define TCP_SOCKET_FLAG 1 -#define UDP_SOCKET_FLAG 2 -#define UNIX_SOCKET_FLAG 3 -int num_of_read_bytes = 0; - -typedef struct sockaddr_in socket_address_ipv4; -typedef struct sockaddr_un socket_address_unix; - - -socklen_t client_addr_len; - -typedef union socketaddr_t -{ - socket_address_ipv4 socket_ipv4; - socket_address_unix socket_unix; - -} socketaddr_t; - -socketaddr_t client_address; -socketaddr_t server_address; - -size_t buffer_size; -int socket_type; - -char* address; -int domain, type, protocol, sin_family, sock; - -void panic(char* message) -{ - perror(message); - exit(SYSTEM_EXIT_FAILED); -} - -int create_socket() -{ - int server_socket; - - server_socket = socket(sin_family, sock, -1); - - if(server_socket == SOCKET_ERROR_CODE) - { - panic("Socket create failed!"); - } - - return server_socket; -} - -void config_server_address() -{ - - if(socket_type == UNIX_SOCKET_FLAG) - { - server_address.socket_ipv4.sin_family = sin_family; - server_address.socket_ipv4.sin_port = htons(SERVER_PORT); - server_address.socket_ipv4.sin_addr.s_addr = inet_addr(address); - - - }else{ - - server_address.socket_unix.sun_family = AF_UNIX; - strcpy(server_address.socket_unix.sun_path, address); - unlink((const char*)address); - } -} - -void bind_server(int server_socket) -{ - - struct sockaddr* address = socket_type == UNIX_SOCKET_FLAG ? (struct sockaddr*)&server_address.socket_unix : (struct sockaddr*)&server_address.socket_ipv4; - - int server_bind_response = bind(server_socket, address, socket_type == UNIX_SOCKET_FLAG ? sizeof(server_address.socket_unix) : sizeof(server_address.socket_ipv4)); - - if (socket_type == UNIX_SOCKET_FLAG) unlink((const char*)address); - - if(server_bind_response == SOCKET_ERROR_CODE) - { - close(server_socket); - panic("Bind server error"); - } -} - -int accept_connection(int client_socket, int server_socket) -{ - socklen_t client_addr_len = socket_type == UNIX_SOCKET_FLAG ? sizeof(client_address.socket_ipv4) : sizeof(client_address.socket_unix); - struct sockaddr *address = socket_type == UNIX_SOCKET_FLAG ? (struct sockaddr*)&client_address.socket_unix : (struct sockaddr*)&client_address.socket_ipv4; - - client_socket = accept(server_socket, address, &client_addr_len); - - if(client_socket == SYSTEM_EXIT_FAILED) - { - panic("Accept connection error!"); - }else{ - return client_socket; - } -} - -void send_buffer(int client_socket, int* buffer, int buffer_size) -{ - socklen_t client_addr_len = socket_type == UNIX_SOCKET_FLAG ? sizeof(client_address.socket_ipv4) : sizeof(client_address.socket_unix); - struct sockaddr *address = socket_type == UNIX_SOCKET_FLAG ? (struct sockaddr*)&client_address.socket_unix : (struct sockaddr*)&client_address.socket_ipv4; - - if(socket_type == TCP_SOCKET_FLAG) send(client_socket, buffer, buffer_size, 0); - else sendto(client_socket, buffer, buffer_size, 0, address, client_addr_len); -} - -int receive_buffer(int client_socket, int buffer_size) -{ - ssize_t bytes_read; - - socklen_t* client_addr_len = socket_type == UNIX_SOCKET_FLAG ? (socklen_t *)sizeof(client_address.socket_ipv4) : (socklen_t *)sizeof(client_address.socket_unix); - struct sockaddr *address = socket_type == UNIX_SOCKET_FLAG ? (struct sockaddr*)&client_address.socket_unix : (struct sockaddr*)&client_address.socket_ipv4; - int received_buffer[buffer_size]; - - while((bytes_read = socket_type == UNIX_SOCKET_FLAG ? recv(client_socket, received_buffer, buffer_size, 0) : recvfrom(client_socket, received_buffer, buffer_size, 0, address, client_addr_len)) > 0) - { - send_buffer(client_socket, received_buffer, buffer_size); - } -} - -void controlc_handler() -{ - exit(SYSTEM_EXIT_SUCCESS); -} - -void server_listen(int client_socket, int server_socket, int buffer_size) -{ - - if (listen(server_socket, MAX_CONNECTIONS) == SOCKET_ERROR_CODE) - { - - close(server_socket); - panic("Listening mode error"); - } - - client_socket = accept_connection(client_socket, server_socket); - receive_buffer(client_socket, buffer_size); -} - -void attribuite_socket_type(int socket_type) -{ - switch (socket_type) - { - case TCP_SOCKET_FLAG: // TCP SOCKET - sin_family = AF_INET; - - address = HOST_IP; - sock = SOCK_STREAM; - break; - - case UDP_SOCKET_FLAG: // UDP SOCKET - - address = HOST_IP; - sock = SOCK_DGRAM; - break; - - case UNIX_SOCKET_FLAG: // UNIXDOMAIN SOCKET - - sin_family = AF_UNIX; - address = "pingpong.socket"; - sock = SOCK_DGRAM; - - break; - - default: - panic("Value error!"); - break; - } -} - -void get_args(int argc, char** argv) -{ - if(argc > NUM_OF_ARGUMENTS) - { - buffer_size = (int)atoi(argv[1]); - num_of_read_bytes = (int)atoi(argv[2]); - socket_type = (int)atoi(argv[3]); - }else - { - panic("Argument is missing!"); - } - -} - -int main(int argc, char** argv) -{ - - get_args(argc, argv); - attribuite_socket_type(socket_type); - - int* buffer = (int*)malloc(buffer_size*sizeof(int)); - - int server_socket, client_socket; - - server_socket = create_socket(); - - config_server_address(); - - bind_server(server_socket); - - for(int i = 0; i < num_of_read_bytes; i++) - { - server_listen(client_socket, server_socket, buffer_size); - } - - return SYSTEM_EXIT_SUCCESS; -} diff --git a/src/socket.c b/src/socket.c new file mode 100644 index 0000000..3a47d5a --- /dev/null +++ b/src/socket.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../include/socket.h" +#include "../include/utils.h" + +int create_socket(int sin_family, int sock) +{ + int server_socket; + + server_socket = socket(sin_family, sock, 0); + + if(server_socket == SOCKET_ERROR_CODE) + { + panic("Socket create failed!"); + } + + return server_socket; +} + +socket_address_unix config_unixdomain_server_address() +{ + socket_address_unix server_address; + server_address.sun_family = AF_UNIX; + strcpy(server_address.sun_path, UNIXDOAMIN_ADDRESS); + unlink(UNIXDOAMIN_ADDRESS); + return server_address; +} + +socket_address_ipv4 config_tcp_upd_server_address() +{ + socket_address_ipv4 server_address; + + server_address.sin_family = AF_INET; + server_address.sin_port = htons(SERVER_PORT); + server_address.sin_addr.s_addr = inet_addr(HOST_IP); + return server_address; +} + +void connect_to_server(void *server_address, int client_socket) +{ + struct sockaddr* address = (struct sockaddr*)&server_address; + + int connection_response = connect(client_socket, + address, + (socklen_t)sizeof(server_address) + ); + + if(connection_response == SOCKET_ERROR_CODE) + { + + close(client_socket); + panic("Server connection error\n"); + } + +} + +void bind_server(void *server_address, int socket_type, int server_socket) +{ + + struct sockaddr* address = (struct sockaddr*)&server_address; + + int server_bind_response = bind(server_socket, address, sizeof(server_address)); + + if (socket_type == UNIX_SOCKET_FLAG) unlink((const char*)address); + + if(server_bind_response == SOCKET_ERROR_CODE) + { + close(server_socket); + panic("Bind server error"); + } +} + +int accept_connection(int client_socket, void *client_address, int server_socket) +{ + socklen_t client_addr_len = sizeof(client_address); + struct sockaddr *address = (struct sockaddr*)&client_address; + + client_socket = accept(server_socket, address, &client_addr_len); + + if(client_socket == SYSTEM_EXIT_FAILED) + { + panic("Accept connection error!"); + }else{ + return client_socket; + } +} diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..75e229e --- /dev/null +++ b/src/utils.c @@ -0,0 +1,23 @@ +#include +#include + +#include "../include/utils.h" + +void panic(char* message) +{ + printf("%s\n",message); + exit(SYSTEM_EXIT_FAILURE); +} + +int* get_init_buffer(int buffer_size) +{ + + int *buffer = (int*)malloc(buffer_size*sizeof(int*)); + + for(int i = 0; i < buffer_size; i++) + { + buffer[i] = (int)(i % 255); + } + + return buffer; +} \ No newline at end of file