From 400953796eb0d372cc20e993e8006d1e7b81b4ba Mon Sep 17 00:00:00 2001 From: Vinicius Silva Date: Mon, 11 Dec 2023 17:08:37 -0300 Subject: [PATCH 1/7] UPD and TCP graphics add --- CMakeLists.txt | 14 ++++++++++++++ graphics/tcp.png | Bin 0 -> 24974 bytes graphics/udp.png | Bin 0 -> 25905 bytes 3 files changed, 14 insertions(+) create mode 100644 graphics/tcp.png create mode 100644 graphics/udp.png diff --git a/CMakeLists.txt b/CMakeLists.txt index d821127..8a7336c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,5 +5,19 @@ execute_process( COMMAND mkdir -p bin ) +#set(CMAKE_CXX_FLAGS "-Wall -Wextra") +#set(CMAKE_CXX_FLAGS_DEBUG "-g") +#set(CMAKE_CXX_FLAGS_RELEASE "-O3") + +# Set warning level for GCC or Clang +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") +set(CMAKE_CXX_FLAGS_DEBUG "-g") +set(CMAKE_CXX_FLAGS_RELEASE "-O3") + +# Set warning level for MSVC +if(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") +endif() + add_executable(./bin/server ./src/server.c) add_executable(./bin/client ./src/client.c) diff --git a/graphics/tcp.png b/graphics/tcp.png new file mode 100644 index 0000000000000000000000000000000000000000..5df077e15402ded70346d18255d57748292112d7 GIT binary patch literal 24974 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 DP<%iT literal 0 HcmV?d00001 diff --git a/graphics/udp.png b/graphics/udp.png new file mode 100644 index 0000000000000000000000000000000000000000..69d88ff41016a55983ce07f820c305675f430652 GIT binary patch literal 25905 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 Date: Sun, 17 Dec 2023 20:32:04 -0300 Subject: [PATCH 2/7] Refactoring pingpong project: Separating code in more files --- CMakeLists.txt | 4 +- bin/client | Bin 17536 -> 21856 bytes bin/server | Bin 17496 -> 21888 bytes include/socket.h | 26 ++++++ include/utils.h | 21 +++++ src/client.c | 231 ---------------------------------------------- src/main_client.c | 125 +++++++++++++++++++++++++ src/main_server.c | 119 ++++++++++++++++++++++++ src/server.c | 224 -------------------------------------------- src/socket.c | 93 +++++++++++++++++++ src/utils.c | 23 +++++ 11 files changed, 409 insertions(+), 457 deletions(-) create mode 100644 include/socket.h create mode 100644 include/utils.h delete mode 100644 src/client.c create mode 100644 src/main_client.c create mode 100644 src/main_server.c delete mode 100644 src/server.c create mode 100644 src/socket.c create mode 100644 src/utils.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d821127..63225d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,5 +5,5 @@ execute_process( COMMAND mkdir -p bin ) -add_executable(./bin/server ./src/server.c) -add_executable(./bin/client ./src/client.c) +add_executable(./bin/server ./include/socket.h ./include/utils.h ./src/socket.c ./src/utils.c ./src/main_server.c) +add_executable(./bin/client ./include/socket.h ./include/utils.h ./src/socket.c ./src/utils.c ./src/main_client.c) diff --git a/bin/client b/bin/client index 6454ae72ad49bd74bd89d61b3c75610f45331179..ac28a2c0db6665d998d540d0e1d534618ac872c0 100755 GIT binary patch literal 21856 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 C;kGRR literal 17496 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 BN4o$3 diff --git a/include/socket.h b/include/socket.h new file mode 100644 index 0000000..19a208c --- /dev/null +++ b/include/socket.h @@ -0,0 +1,26 @@ +#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 + + 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_client.c b/src/main_client.c new file mode 100644 index 0000000..c496830 --- /dev/null +++ b/src/main_client.c @@ -0,0 +1,125 @@ +#include "../include/socket.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; + +socket_address_ipv4 ipv4_server_address; +socket_address_unix unix_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(socket_type == UNIX_SOCKET_FLAG ? (void*)&unix_server_address : (void*)&ipv4_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(socket_type == UNIX_SOCKET_FLAG ? (void*)&unix_server_address : (void*)&ipv4_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); + ipv4_server_address = config_tcp_upd_server_address(); + connect_to_server((void*)&ipv4_server_address,client_socket); + break; + + case UDP_SOCKET_FLAG: // UDP SOCKET + client_socket = create_socket(AF_INET, SOCK_STREAM); + ipv4_server_address = config_tcp_upd_server_address(); + connect_to_server((void*)&ipv4_server_address,client_socket); + + break; + + case UNIX_SOCKET_FLAG: // UNIXDOMAIN SOCKET + client_socket = create_socket(AF_UNIX, SOCK_DGRAM); + unix_server_address = config_unixdomain_server_address(); + connect_to_server((void*)&unix_server_address,client_socket); + + 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); + + for(int i = 0; i < num_of_read_bytes; i++) + { + socket_listen(); + + printf("%lf\n", (float)(elapsed_time_ms)); + } + + return SYSTEM_EXIT_SUCCESS; +} diff --git a/src/main_server.c b/src/main_server.c new file mode 100644 index 0000000..c0bebee --- /dev/null +++ b/src/main_server.c @@ -0,0 +1,119 @@ +#include "../include/socket.h" +#include "../include/utils.h" + + +int num_of_read_bytes = 0; + +socklen_t client_addr_len; + +int server_socket, client_socket; + + +socket_address client_address, server_address; + +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); + config_tcp_upd_server_address(); + break; + + case UDP_SOCKET_FLAG: // UDP SOCKET + + server_socket = create_socket(AF_INET, SOCK_DGRAM); + config_tcp_upd_server_address(); + break; + + case UNIX_SOCKET_FLAG: // UNIXDOMAIN SOCKET + server_socket = create_socket(AF_UNIX, SOCK_DGRAM); + config_unixdomain_server_address(); + 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)); + + bind_server((void*)&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/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..5c9c3f9 --- /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, -1); + + 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 From cafe400c4e3d00fbf0e9c0849a965b764808f2c4 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Sun, 17 Dec 2023 20:35:52 -0300 Subject: [PATCH 3/7] Add bin to .gitignore --- bin/client | Bin 21856 -> 0 bytes bin/server | Bin 21888 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100755 bin/client delete mode 100755 bin/server diff --git a/bin/client b/bin/client deleted file mode 100755 index ac28a2c0db6665d998d540d0e1d534618ac872c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21856 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 C;kGRR From a57ae65695055d082ad975aad307a1211ef40408 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Sun, 17 Dec 2023 23:56:48 -0300 Subject: [PATCH 4/7] Basic pipe connection implemented --- include/pipe.h | 15 +++++++++ include/socket.h | 15 ++++----- src/main_client.c | 14 +++++++++ src/main_server.c | 15 +++++++-- src/pipe.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 128 insertions(+), 9 deletions(-) create mode 100644 include/pipe.h create mode 100644 src/pipe.c diff --git a/include/pipe.h b/include/pipe.h new file mode 100644 index 0000000..b929081 --- /dev/null +++ b/include/pipe.h @@ -0,0 +1,15 @@ +#ifndef __PIPE_H__ + + #define PIPE_ERROR_CODE -1 + #define PROCESS_ERROR_CODE -1 + #define NUM_OF_PIPE_DESCRIPTORS 2 + #define CHILD_PROCESS 0 + + extern int *create_pipe(); + extern pid_t fork_process(); + + extern void server_write_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer); + extern void server_read_pipe( int* descriptors, pid_t child, int buffer_size, int *buffer); + extern void client_read_pipe( int* descriptors, pid_t child, int buffer_size, int *buffer); + extern void client_write_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 index 19a208c..a12e954 100644 --- a/include/socket.h +++ b/include/socket.h @@ -2,15 +2,16 @@ #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 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 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; diff --git a/src/main_client.c b/src/main_client.c index c496830..816a42b 100644 --- a/src/main_client.c +++ b/src/main_client.c @@ -1,4 +1,5 @@ #include "../include/socket.h" +#include "../include/pipe.h" #include "../include/utils.h" #define N 10000 @@ -12,6 +13,9 @@ int* buffer; size_t buffer_size; int socket_type; +pid_t child; +int *descriptors; + socket_address_ipv4 ipv4_server_address; socket_address_unix unix_server_address; @@ -86,13 +90,23 @@ void attribuite_and_init_socket(int socket_type) connect_to_server((void*)&unix_server_address,client_socket); break; + + case PIPE_CONNECTION_FLAG: // PIPE CONNECTION FLAG + descriptors = create_pipe(); + child = fork_process(); + + server_read_pipe(descriptors, child, buffer_size, buffer); + + break; + default: panic("Value error!"); break; } } + void get_args(int argc, char** argv) { if(argc > NUM_OF_ARGUMENTS) diff --git a/src/main_server.c b/src/main_server.c index c0bebee..0dd150d 100644 --- a/src/main_server.c +++ b/src/main_server.c @@ -1,16 +1,20 @@ #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, server_address; +int *buffer; size_t buffer_size; int socket_type; @@ -79,7 +83,14 @@ void attribuite_socket_type(int socket_type) server_socket = create_socket(AF_UNIX, SOCK_DGRAM); config_unixdomain_server_address(); break; + + case PIPE_CONNECTION_FLAG: // PIPE CONNECTION FLAG + descriptors = create_pipe(); + child = fork_process(); + + break; + default: panic("Value error!"); break; @@ -106,7 +117,7 @@ int main(int argc, char** argv) get_args(argc, argv); attribuite_socket_type(socket_type); - int* buffer = (int*)malloc(buffer_size*sizeof(int)); + buffer = (int*)malloc(buffer_size*sizeof(int)); bind_server((void*)&server_address, socket_type, server_socket); diff --git a/src/pipe.c b/src/pipe.c new file mode 100644 index 0000000..5b928c0 --- /dev/null +++ b/src/pipe.c @@ -0,0 +1,78 @@ +#include +#include + +#include "../include/pipe.h" +#include "../include/utils.h" + + +int *create_pipe() +{ + int pipe_descriptors[NUM_OF_PIPE_DESCRIPTORS]; + + if(pipe(pipe_descriptors) == PIPE_ERROR_CODE) + { + panic("Pipe creation failed"); + } + + return &pipe_descriptors[0]; +} + +pid_t fork_process() +{ + pid_t child_pid; + + if((child_pid == fork()) == PROCESS_ERROR_CODE) + { + panic("Fork failed"); + } + + return child_pid; +} + +void client_write_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer) +{ + close(descriptors[0]); + write(descriptors[1], buffer, sizeof(descriptors)); + close(descriptors[1]); +} + +void client_read_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer) +{ + if (child == CHILD_PROCESS) { + close(descriptors[1]); + + read(descriptors[0], buffer, sizeof(buffer)); + close(descriptors[0]); + }else + { + server_write_pipe(descriptors, child, buffer_size, buffer); + } +} + + +void server_read_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer) +{ + + int* received_buffer = (int*)malloc(buffer_size*sizeof(int)); + + if (child == CHILD_PROCESS) + { + close(descriptors[1]); + + read(descriptors[0], received_buffer, sizeof(buffer)); + + close(descriptors[0]); + exit(EXIT_SUCCESS); + }else + { + client_write_pipe(descriptors, child, buffer_size, buffer); + } +} + + +void server_write_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer) +{ + close(descriptors[0]); + write(descriptors[1], buffer, sizeof(buffer)); + close(descriptors[1]); +} \ No newline at end of file From 753338e657b3a822a924f73f272015bdf2f1defd Mon Sep 17 00:00:00 2001 From: Vinicius Date: Mon, 18 Dec 2023 02:56:22 -0300 Subject: [PATCH 5/7] Fix tcp connection --- CMakeLists.txt | 12 +++++-- bin/client | Bin 0 -> 26328 bytes bin/server | Bin 0 -> 22368 bytes include/pipe.h | 9 +++--- src/main_client.c | 13 ++++---- src/main_server.c | 28 ++++++++++------ src/pipe.c | 81 +++++++++++++++++++++------------------------- src/socket.c | 13 +++++--- 8 files changed, 84 insertions(+), 72 deletions(-) create mode 100755 bin/client create mode 100755 bin/server diff --git a/CMakeLists.txt b/CMakeLists.txt index 63225d6..ed3c494 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,5 +5,13 @@ execute_process( COMMAND mkdir -p bin ) -add_executable(./bin/server ./include/socket.h ./include/utils.h ./src/socket.c ./src/utils.c ./src/main_server.c) -add_executable(./bin/client ./include/socket.h ./include/utils.h ./src/socket.c ./src/utils.c ./src/main_client.c) +set(SOURCE_FILES + src/socket.c + src/pipe.c + src/utils.c +) + +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 new file mode 100755 index 0000000000000000000000000000000000000000..dea2ffec8266f081a223473ffeefd0ef659c6f53 GIT binary patch literal 26328 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 literal 0 HcmV?d00001 diff --git a/bin/server b/bin/server new file mode 100755 index 0000000000000000000000000000000000000000..56da69ac648dd1c5fb68ef2992bdefa6de5a02cb GIT binary patch literal 22368 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 U!X_h=Pycgkg~W7+f`euM1CiD#9{>OV literal 0 HcmV?d00001 diff --git a/include/pipe.h b/include/pipe.h index b929081..c4a04b4 100644 --- a/include/pipe.h +++ b/include/pipe.h @@ -5,11 +5,10 @@ #define NUM_OF_PIPE_DESCRIPTORS 2 #define CHILD_PROCESS 0 + #include + extern int *create_pipe(); extern pid_t fork_process(); - - extern void server_write_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer); - extern void server_read_pipe( int* descriptors, pid_t child, int buffer_size, int *buffer); - extern void client_read_pipe( int* descriptors, pid_t child, int buffer_size, int *buffer); - extern void client_write_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer); + + 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/src/main_client.c b/src/main_client.c index 816a42b..cc79aac 100644 --- a/src/main_client.c +++ b/src/main_client.c @@ -42,8 +42,7 @@ void send_buffer(void *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(socket_type == UNIX_SOCKET_FLAG ? (void*)&unix_server_address : (void*)&ipv4_server_address); + receive_buffer(server_address); } void controlc_handler() @@ -96,8 +95,6 @@ void attribuite_and_init_socket(int socket_type) descriptors = create_pipe(); child = fork_process(); - server_read_pipe(descriptors, child, buffer_size, buffer); - break; default: @@ -128,12 +125,16 @@ int main(int argc, char** argv) buffer = get_init_buffer(buffer_size); + float sum_elapsed_time_ms = 0.0; + for(int i = 0; i < num_of_read_bytes; i++) { - socket_listen(); + socket_type == PIPE_CONNECTION_FLAG ? elapsed_time_ms = pingpong_pipe(descriptors, child, buffer_size, buffer) : socket_listen(); - printf("%lf\n", (float)(elapsed_time_ms)); + 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 index 0dd150d..411534c 100644 --- a/src/main_server.c +++ b/src/main_server.c @@ -12,7 +12,9 @@ pid_t child; int server_socket, client_socket; -socket_address client_address, server_address; +socket_address client_address; + +void* server_address; int *buffer; size_t buffer_size; @@ -69,19 +71,22 @@ void attribuite_socket_type(int socket_type) { case TCP_SOCKET_FLAG: // TCP SOCKET - server_socket = create_socket(AF_INET, SOCK_STREAM); - config_tcp_upd_server_address(); + 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); - config_tcp_upd_server_address(); + 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); - config_unixdomain_server_address(); + 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 @@ -114,17 +119,20 @@ void get_args(int argc, char** argv) int main(int argc, char** argv) { + printf("OI0"); get_args(argc, argv); + printf("OI1"); attribuite_socket_type(socket_type); buffer = (int*)malloc(buffer_size*sizeof(int)); - - bind_server((void*)&server_address, socket_type, server_socket); - + printf("OI2"); + //bind_server(server_address, socket_type, server_socket); + printf("OI3"); for(int i = 0; i < num_of_read_bytes; i++) { server_listen(); } + printf("OI4"); return SYSTEM_EXIT_SUCCESS; } diff --git a/src/pipe.c b/src/pipe.c index 5b928c0..8f19606 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -7,14 +7,14 @@ int *create_pipe() { - int pipe_descriptors[NUM_OF_PIPE_DESCRIPTORS]; + 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[0]; + return pipe_descriptors; } pid_t fork_process() @@ -29,50 +29,43 @@ pid_t fork_process() return child_pid; } -void client_write_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer) +float pingpong_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer) { - close(descriptors[0]); - write(descriptors[1], buffer, sizeof(descriptors)); - close(descriptors[1]); -} -void client_read_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer) -{ - if (child == CHILD_PROCESS) { - close(descriptors[1]); + 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)); - read(descriptors[0], buffer, sizeof(buffer)); - close(descriptors[0]); - }else - { - server_write_pipe(descriptors, child, buffer_size, 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)); } -} - - -void server_read_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer) -{ - - int* received_buffer = (int*)malloc(buffer_size*sizeof(int)); - - if (child == CHILD_PROCESS) - { - close(descriptors[1]); - - read(descriptors[0], received_buffer, sizeof(buffer)); - - close(descriptors[0]); - exit(EXIT_SUCCESS); - }else - { - client_write_pipe(descriptors, child, buffer_size, buffer); - } -} - - -void server_write_pipe(int* descriptors, pid_t child, int buffer_size, int *buffer) -{ - close(descriptors[0]); - write(descriptors[1], buffer, sizeof(buffer)); - close(descriptors[1]); } \ No newline at end of file diff --git a/src/socket.c b/src/socket.c index 5c9c3f9..8194e01 100644 --- a/src/socket.c +++ b/src/socket.c @@ -14,7 +14,7 @@ int create_socket(int sin_family, int sock) { int server_socket; - server_socket = socket(sin_family, sock, -1); + server_socket = socket(sin_family, sock, 0); if(server_socket == SOCKET_ERROR_CODE) { @@ -45,11 +45,13 @@ socket_address_ipv4 config_tcp_upd_server_address() void connect_to_server(void *server_address, int client_socket) { - struct sockaddr* address = (struct sockaddr*)&server_address; + socket_address_ipv4 server = config_tcp_upd_server_address(); + + struct sockaddr* address = (struct sockaddr*)&server; int connection_response = connect(client_socket, address, - (socklen_t)sizeof(server_address) + (socklen_t)sizeof(server) ); if(connection_response == SOCKET_ERROR_CODE) @@ -64,9 +66,10 @@ void connect_to_server(void *server_address, int client_socket) void bind_server(void *server_address, int socket_type, int server_socket) { - struct sockaddr* address = (struct sockaddr*)&server_address; + socket_address_ipv4 server = config_tcp_upd_server_address(); + struct sockaddr* address = (struct sockaddr*)&server; - int server_bind_response = bind(server_socket, address, sizeof(server_address)); + int server_bind_response = bind(server_socket, address, sizeof(server)); if (socket_type == UNIX_SOCKET_FLAG) unlink((const char*)address); From 470878e3b2521f98cfd6e378286abe9ba3504eb3 Mon Sep 17 00:00:00 2001 From: Vinicius Date: Mon, 18 Dec 2023 03:33:48 -0300 Subject: [PATCH 6/7] Fix bind server bug --- CMakeLists.txt | 6 ++++++ bin/client | Bin 26328 -> 22168 bytes bin/server | Bin 22368 -> 22328 bytes src/main | Bin 0 -> 18272 bytes src/main_client.c | 20 +++++++++++--------- src/main_server.c | 10 +++------- src/socket.c | 11 ++++------- 7 files changed, 24 insertions(+), 23 deletions(-) create mode 100755 src/main diff --git a/CMakeLists.txt b/CMakeLists.txt index ed3c494..ea7bae9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,12 @@ set(SOURCE_FILES 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) diff --git a/bin/client b/bin/client index dea2ffec8266f081a223473ffeefd0ef659c6f53..3232dcf1c4b1aa0f1286d72c7dd4f9048d2fbc90 100755 GIT binary patch literal 22168 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 Qa_M)>O>g5RD)57rLA}~nM{&-Br|d5jsyh_ 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 diff --git a/bin/server b/bin/server index 56da69ac648dd1c5fb68ef2992bdefa6de5a02cb..14f5cffb223480f558a57852dd3a5de334be4ba3 100755 GIT binary patch delta 4994 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 Ji^^vW|1U#T3HJa1 delta 5318 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 S1~bZZ8eUk%Hjv|{N&f>yhe)dc diff --git a/src/main b/src/main new file mode 100755 index 0000000000000000000000000000000000000000..6f3487a18fea34a82c9dfee309bb0cb84c961430 GIT binary patch literal 18272 zcmeHP4UkmTmA*Yg!>GVC1`;p|jS&l?v@?JPlc3E{NPMS06pyJxnh>-EH@4 z1tU5*koeL}Id0rUvuiD8*VSaRwOG+aQ!(_Y5lpEWT#}lUWHS=2^eiL}BkHJV?|1G! z_s#3a^t!dXRlBvtrFzag-}$-co_pWD@9%O)^{!=cQ|unb4H#ptAmTEB;@pua)hFg3^uf(w`_;XsYY` zBJ5;7S^iN(ck^{zU#)%+I{!>Lz2cHovi-7Um!#s0Q^|B;>*B4;FI#-svQRz~S|Y2a zxPti6n7ZnkHi3RC5vJYMbt_)`BiT%rlm5!KTl~j-51hzME%%(4y<_aw`Pp+xhvFt1 z(xF2B_!N>n9iN9E>8O0{kT_vf4kljeQb!a2{S4rl*U-PF20jHijg?bMER~6E5vCd28Z|qT>1Zl> zYeM7_(YWY}rXUly9_OBb>}JGjBz6mf00erbQmU5|)Ts znWQMBafWY^njN`Jm&g{Zyg+UFgvchd3F%3+C)07!X=T!R(UHk*5vgR}N~A?J7E5F; zk=UBFPzx%EZ82k=Tg;AVG9|LPWZLQw$#lXpqw#nSM(r`0K`s+lUEQ*3wYem;%sE;* zez+ubsW4kMtTW?@Tw*g-l-sawbt;oiY>2j}5~yf%S0>HPF_r3siZpZ7SIiQ!fUYFPxJ+gX;U8?l@kz^g0uy$q%K$ zgAeg_MnhPNh1S>nAYXUTTt{=CE<-My=1pD7E_{XtK}THpIWBz6h3h$##IqTv@ra@A zl%NaOb3F+cx^Q`&!4^#}T+P=?u-t`H9lC^FxXuO13>S_>JEhfypXs1NY;@s#NhGD4 zT=-O%ey0mZM>{3!!lyf^5L;b1Uph%?w+q)}hXi-IaQA%E=fZg?NI&?9os|*-D&o(?G!>(LCo))^%VV}d(0yjE* z{6pPdTG-Hjho=h-wBO-rfkXQpo)$K=-{EONL;D?`7BaNo;b{Rw`yHMZF0^0s=#3S! zH`WN*AK=$5rrsInBOZQ*hriUrFZS>YJp6ecewK%y=HdMw{)3CF<9o})|G~q*?%{vq z;eYAjU-a-l^YBl3_{Tl`KY93vJp2P5{;%A8^B-F5gEt!X5u@j|k=6~7=2G+XM(>K( zFbpfR^3Xid5o(;b6P<_?taruzK#X4hUlO@|%$kK$?|M4Msdq+YsBvC5={>^~`bnvO zX*-cc9~$gdq0 zU$>?j#TApml)w8yrBaS#us`Sj;38b@-T+&tezG6F1wuM#gB>P|puPQ=T__jVm5Y&M zbfYWmm+bvzIv?!F$)4>eD}_ch@FARb2JkVQ?#0N-=bzCo)*CyH-6x}XsuP~$Msd=D zg_4hyn@b)0cV&V4kRy3u^pxt1pJtQk&Dl(Pv#}3%Q1a%@u$v5fYXd5}jw=#qh*8`{ zK8<28IWdY4Y$akh81_cYaqGH`;th8hwh;h78+;%5`@jdmF9g2_{3GDudgF5Nd%-^e zJ`COfUjlysd@J~kMzL+cuv<43+Xn5{&c+|L9qzDOQ${gTjvE)LCRzUS_fEQ^x?yZQ z4U|cD+sCNwk)b-VZ~lCA%bl?6up>v%z#SM#l*!)$vLmmdh9T5lMm%GvX{t;fY6?SK zL}69Z2+JoOTd48r4JG4kw>X@WCkryi449_rbCs8W~%5u#WG z2tmD#S(k#EgV`Nvj8G^}qaT02Mksb$X~JlJkHLcoCWxlwie|2k=GpoJ#xDX!0B4{s z9bXB&4Ic4jIKFLIjZTSgmN&j8d;4L-E)3XhgP!>IM~=~YgA}2&BO^v{+cBhRL{?72 z{@ZY6M-KOFKkO^aK)q*hy*|`?w7wWQjIN^G%+%d<|9hU?1olw{~)W*PXDUv^pfJ#xe+=D+D;&0Di83G2^00xufxo(wj!(r%P`(2By7=%YZi< zZ|om_hy#`Of9 zR{nuV7M9)~D@!nG74@)-c>-EnBglvoz{Y#|KSD0rM zXU)ZN(Lb_)0x6WAq=*pm;5(Jd(N9BMfuQI=NPoAVKnI}th4M=K-4^?R)_noGed95# zM+%m^Pe3dPhCO81&lvk7B{?ni`tPFpYz(lX{{eaUw9)f#KFnhSEp}<8^laGA?UVW8 zJUt;zd&)k;H?WV6<+5eG^Nz8l6fo?5W5=svg!=o4vFPW<<%g`Zu}0CuFQaGo1!Hvm zcXZgWpWbn#f@5RRq4DEgFI#~H674BB7``E+rvbr%l;JP! z)B*d;bFttSXZ_(*6#h~CHF~EVBO<4Rzr}Q5`wxLvlg%8ue7(WB2ta=OsG6s4!<6Li zaV_}eey^Ds0tbN8sj)Hm+D+r`{H=rBHOy3((+K0n+KShi&!-H?<&i=k%wuXF;k z)S1X+M+M#UZN&O4t32i^0QbLaRs}#I1 z(i_pmzT zlg&{o7sE;(J^zfnw?d;D#_xv7+5fLXZvfWI3+iADZ&R#9kltM+;`8zHLtSy}>+R+x zp9wYLU$a=B$laXC1^HD=GLsG_a=A?IOtA`YNrHJLm5^8|Uyz)lI$yNn)rzW->{XpA zv$w9fTE1LC^}()8JfWP6>!YaxAI}#nbDIlYiL@0==7U|yd>*><#kDO>_%-9V1iz*D zEyLZ+C+k1=6F8<@>hK$t$_VHHX8PIa^dZnD&`qP2${_F-8b#oDgLZ;`1H*nd=qM;% zcx`{HQh5RNJedqE!t9RQt)^X3HT zg`o5uz&)T%pk-X$wt~hmOtYX=^s{f@t=9?P)`0JmQ>Qfap>D$Id2{#iN(GCs5NoE; zvL-N33p868f5f>7JuyA7cKYluG@f-!L$|o{oX>uG=>_KlmG*xQx)(W-h6JLJUkkrS zfOnHU7piMFe($2b)r3W+2fkXjdfMb$5fIoQe&5IMT;y^J*=f1aQ(yPC(jgxM_*I}| zf;u{N*GmPGQ~z9n{1>a_cRKO_e18}6Jyr5=NqG<$_2(k=*KJkuyb1sq)v*COJD?MG z>)fJLNNz#?Ams8rf^NsUarwQFe+zP%UoEfynvXPQ!~QYIr(i6|e$jH^LHq_Fn*rJF zI390*p(?%;(Aff=omDztkvc(OGck5(h3SHx<0H~jUvJ6~WDLupGaKVizH4#CAlnbw zbjY?;`EQs0W&0ujGUQ)!`>(%7Iw$$PkoRFMf2GPk=h#06`BBK}oO0r;`-Rg+f=`#z z891GR(-}COfzuf{oq^LC_}|JvkS=&p^mj;f$wTE?MZ{F5`a`H`%%3|?9n8^k{;o-X z8$#E_RL)Vv`R<9XpQvd0TOU?3#P8+neLpcMk4#pSi5O(L{>En+2Z~o8ve0!W756tW z#IuY9;+vu{(^jUNm}Z%FGwox# zhv{CXC8h&RhnS8q75tG}fN79v6Vou$R;HVnW|?*~?PI!!skc2J#W#eN##O6Ve>S+V zt-X-83c=>)(6Ug|;^u;6n{QvTB-FHQ5yStnM;e}!#PNz(i^hu&lHJ^)K~|twL_3HUS z<9A7YoMn8zYy4pxOcej#8u*WD;QMOewes^K^nEysvvlL{DHFx>3Uqwp6T&<0Uz4^U zbH2yduHKRQm|b}O(D*bY@NDEK#S@6U=Z7%F_{%&I$@_TVVc;{6|E93=Fi8=yR_Zh3 zB6RO5?_FIO9a=T;uK^EwbctPvaTXMqrNh<2zmt9fVlq$2@?ID!k4n5+m$(PvhvL62 ztYkX=r=d^y1s?q68h&15{h&wxZN_(caC(bKd47^7X8mpBbl_BPw@3dItbc+RBAvs9 zzyrvG9{+;NB~o8=<8&qaspkc3CyVHb?b&rRgkJx&#rhh4;+(hEu+r4)0zDqqv1uPf zyKCV0)WH8<;sJ33CuR>j+rsr`!wS&#(sMY8vdULPI(TqA3bf;z9zyK zdi=ju!_V6_@F|FMqCC*PDDuCY{p<0zmh0W=pHSBa}*_uu0+@JR@4qJEhJJb?K7!fr1@T+H=` zc|FqOYOeGX5Q})8T+L<|v!8&+&!4dVYQB(?&(L7AT;kPr64wHp^0_svWME}!Wk0{* z{*})vA-S=JpPOpnchU10@) zmE{Ny&gWw{`GEY?;c8u{ebuy&wKJ2D^xD2;YX~G z<*epV2D>t%?Mc&$ZWaLYR-vOK6cgh+I83X{#HNyTA`i`Y#@w9Bv`14W_Ne6YX0)&s z8&|rrsf3k?hngnVpj|IXGn&gqx0!hLk=rIZa?!4Y8838oZG(x6Gogt+CoWa>%@iV{ zEiE7gE1AlJ(ry@2y|Dpjnrp9Hxh`Txu32MZW67E?U$b&u%WA;bjb=s+mKtlW6XsP{ zU%P7M)#kNp*RGFjFgL7Rb#=s~%{Lv%&1NB;+#1igT+8h*i9EK|sNFfHmElT7tTUO4 z%gr}oy(vcSfAMbFairKNqju~#$Vcs$QO$!xxn+m8_f(n2Qc0v!hG?d+r$_E1s?tao zy39<6Nt=z#_H7or5HFmt$EPcqLMLE5keSV8V$?oRD-+A4sG(LalZu(0(R4hO$O$tM zk6KaMR}|Y)<(xJune7-Zq(ohebXRXAa@3cp9Y_vO4JY#|KW9_Lfb!VT>{%rw$&EltK(g_m;bAucR!` zfGSv7n|ZZEFP2E&oX{g&bxM`C2<5kRS5P>KZB7?LIKi@s zoVCpbp|`P1HyLMW<*Js&Gz&}h&S<_k zmI%pKhHx0#oB>M*`9w^Fti)EZ@|+FjGV=TmB|3Q`?!<;ahf_Y(jI1p5F{;8m0%yt` z14M+d6wu3UUcvr*gl+?HYawviC<|RzQqhzz&lHHir0Xu90z;2twEc3n*R;v4jAOly zYWOl7xb40B%P-K1O!YdiVY+X3+w12Bng+EZQ?LD(fa6tZM#rz8vuUd9pUn2&_@lt- z8Jo5rlM_WC)XrX^O?^?Td@Ew*39diuGdreStW_LMWP z{e!?LC)&SreaF{%e47gmRlNQGH-O#tLAKLWUl(h8efg;A!yfy+{CrJQtyjx_ugAW` z_L_EkI$ZnH^huAszQ54)75xC11JHIl9(tbSZoj^7*Hk~x*81N3{fzB(|BE1NGW{*H znt1Ki^QrOiGsJe9{zMxx_1eDzoZ{E@@0qU@H9e#SY_G=;v*L9e&~_d^ZO5P6Emj&{ zea&ln9BPd&d;OfS;Xi5r0c>gP>iYF_H~s&6j8NlH==`Ii>(%}EkHAPp+dI$UE+K6c zwpYx!z4kL1@+$i+#xaekzQ~m#$ym*9F+VTPrg4`kTS^v$~_L?Jsf=bwIIF zaZ^thOL Date: Mon, 18 Dec 2023 11:53:38 -0300 Subject: [PATCH 7/7] Connection graphics generated --- data/graphic_with_bloxplot.py | 34 ++++++++++++++++++++++++++++++++++ data/main.py | 33 ++++++++++++++++++++++++++------- graphics/full.png | Bin 0 -> 50394 bytes graphics/full_box_plot.png | Bin 0 -> 52044 bytes 4 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 data/graphic_with_bloxplot.py create mode 100644 graphics/full.png create mode 100644 graphics/full_box_plot.png 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 0000000000000000000000000000000000000000..05c364333f12b7179bed05571c297be829e5d319 GIT binary patch literal 50394 zcmeFZc|6s7yFRXI*KXYHQX<-Inh2#Nb0bNTc_x|3ka-9VJMBnnnNp%MTZY0iPdiB{ zGAuHaWF~Xw-}T0R&htIr=bZ0(o!{`!?|41CM_ShUeBPh;ec#u8UDy4-cj= z&ECM;#>CR%2#){{-@)IEZEdY=gm`()|M3DIOKT(E16m#Kc$1&4&Z*fjFl^E#|1FCa zk1}Ckcq=J&=A@!ya9@*Cu(#cO(a=QDk!i7l4~O)22i)rEibl`=7UE`2Xc1SgGCf_NIFaGCa`BtpY zSC@O;)s>NzH6E|&E!?i7XlNKom0nr)G)5t+M|^(LXLxvc>y|BH&x9RfC4Jbor+7q# zIG^9^D^>J>m21M$Ya4ep%}k|X#C3YSZuZ&O@UZ+?51sy6Pja?Xe7@r5iq$2Wdh}Q& z18s#oH`fiULW(Zqeb-`}D<{OOYI9wuIi&FA{G;tIJ;g*}a(bHUx8F{vXkNQBH{CMN z$<6)IzCS@Lt3F3eL`1W{A+5GC!^VK7{w%gi4OcKfRhw5LI$mcKiu*9Zhoq*q72GY= z=ZjIID)X%mtL$aWvn&^%&yF|$^7fuVf<|Avk9a__eq||d-c>U%Z*N+T02>?I+6^0& zN&~p<26HA%`|D|p0U8#M@TNb8+Dk>XXM$$>lFP4}7tV_gkB!mE^<+ny)h3u?`R~lGWN5W+ z>+V5>-^e+j5E-qVxN z`s3#zcLgpz3phmg@?e#C|+C z{P@Jc!A)MC;yl{*0^6ZCwZWn)Z*GjYe`6TV}=Tjed1kYXS(!Cy#kL7Rpb2)V@MRy?(=i01WLY~yq5w(}fJ)4`v9g;y#N%=8==hgocj zp2`TXfI$=0(3HMd;M#U)yJDJ! z7G4q~9mrFkX=fIcE38oUgx~C_MdR_aXU^mzS52*~7`Lm6_7m>mLvp7`1xW^-G&KZzidFes0#T>(dMC za?$HQUJYdS@|-<;wz#NB^5athlJ;0LeK>OF=cao;y|_IyJ4>#$?3r+bw}@Z3inh~P zyeiPg$LD2O7{BwVaaK%AWp{T@L#nw#nnlys!NJ7GkC{F`J{;CKC-dZ})CQJget5BI zZ9=@{E>}e-C#O^!j}0t)v0~;exlIGK9G3}YRn^B2b_#w`bfu)&_p6U}S4r;Py?c0K zLM4z#E5-05bCwO?kt6)}eX51;-j(1wA3b`6`wu*3(b(0c;at{J6Hi5jIUp{c*Eo@w zGSHMIO&K3(a?$Q_njNdP`|(}(;}d@Bg=kJGIXSr}$FF_aktjFg@SCu3)|)()!m_a= z{RcN~+9ZSBuaSDSV!O`uYs$4kX^vBepMx+)7h3{>;x&Ab$7c04^lH<3q=lwrA> z(1tCKd?wr0*7gMP(Qnj}m^T+|nL8;_aCcMMIwdc%>rJbpA4STBCiw1?t!Kq%m+LHh zHr94`S3S)giNmxmsbfdfSMn{npG>>nNaUUF+ndC!qIVVINzT8&@>HM^_?wi_N9)@W)_5g=Nc@Wp+nC?R#^F)J=S(GM>oja4Byu z3W&-xA-ld?dnFT<`sU{b=TppTd1OLF)Q~W0SuC?(>3S$!|~TR25!wRl2&m%wpHm$ptqEq5}7PejS!O`He;Nd;SWtaMm_9^gMU>ySJXY z3}i?q8)h>xQ1@L&CW327+JuslSo+jXyO zNSyFswgT$a6Fvh^@>gV|UZl>nXCu`LvL>Tl6`l_s)O-j!!f*WPw;UwcOzeBbOP4M? z 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

8NR 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 literal 0 HcmV?d00001