From f7454077375f3b866140876b09dbb6c71b0a2ebc Mon Sep 17 00:00:00 2001 From: Lukas Jiriste Date: Tue, 23 Jan 2024 12:36:32 +0100 Subject: [PATCH] Rework communication protocol Before client relied on a delay for server to be able to recieve. Now this mode is only used for sharing PID of client. After server knows client's PID, it signals the client when it is ready. --- src/client.c | 87 ++++++++++++++++++++++++++++++++++++++++++--------- src/server.c | 88 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 139 insertions(+), 36 deletions(-) diff --git a/src/client.c b/src/client.c index c9e2a37..e6c4f37 100644 --- a/src/client.c +++ b/src/client.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/20 17:15:06 by ljiriste #+# #+# */ -/* Updated: 2024/01/20 18:14:47 by ljiriste ### ########.fr */ +/* Updated: 2024/01/23 12:29:57 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,34 +15,89 @@ #include #include -void send(pid_t server_pid, const char *message) +int g_may_send; + +void handler(int signum) +{ + if (signum == SIGUSR1 || signum == SIGUSR2) + g_may_send = 1; + return ; +} + +void send_bit(pid_t server_pid, int bit) +{ + if (bit) + { + kill(server_pid, SIGUSR1); + } + else + { + kill(server_pid, SIGUSR2); + } + return ; +} + +void send_message(pid_t server_pid, const char *message) { int char_bits_sent; - int char_ind; + size_t char_ind; + size_t message_length; char_bits_sent = 0; char_ind = 0; - while (1) + message_length = ft_strlen(message); + while (char_ind <= message_length) { - if (message[char_ind] & 1 << char_bits_sent) - kill(server_pid, SIGUSR1); + if (!g_may_send) + pause(); else - kill(server_pid, SIGUSR2); - ++char_bits_sent; - if (char_bits_sent == CHAR_BIT && message[char_ind] == '\0') - break; - if (char_bits_sent == CHAR_BIT) - ++char_ind; - char_bits_sent %= CHAR_BIT; - usleep(1000); + { + g_may_send = 0; + send_bit(server_pid, message[char_ind] & 1 << char_bits_sent); + ++char_bits_sent; + if (char_bits_sent == CHAR_BIT) + ++char_ind; + char_bits_sent %= CHAR_BIT; + } } return ; } +void send_pid(pid_t server_pid) +{ + pid_t my_pid; + size_t bits_sent; + + bits_sent = 0; + my_pid = getpid(); + while (bits_sent < sizeof(pid_t) * CHAR_BIT) + { + send_bit(server_pid, my_pid & 1 << bits_sent); + ++bits_sent; + usleep(100); + } + return ; +} + +void setup_handler(void) +{ + struct sigaction sa; + + ft_memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGUSR1); + sigaddset(&sa.sa_mask, SIGUSR2); + sa.sa_handler = handler; + sigaction(SIGUSR1, &sa, NULL); + sigaction(SIGUSR2, &sa, NULL); + return ; +} + int main(int argc, char **argv) { pid_t server_pid; + setup_handler(); if (argc != 3) { ft_printf("Invalid number of args. Th call should look like:\n" @@ -55,6 +110,8 @@ int main(int argc, char **argv) ft_printf("%i is not a valid PID.\n", server_pid); return (0); } - send(server_pid, argv[2]); + send_pid(server_pid); + send_message(server_pid, argv[2]); + ft_printf("Message sent succesfully.\n"); return (0); } diff --git a/src/server.c b/src/server.c index cc4aa65..1661533 100644 --- a/src/server.c +++ b/src/server.c @@ -6,7 +6,7 @@ /* By: ljiriste +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/20 15:12:04 by ljiriste #+# #+# */ -/* Updated: 2024/01/20 18:12:40 by ljiriste ### ########.fr */ +/* Updated: 2024/01/23 12:36:00 by ljiriste ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,24 +17,19 @@ typedef struct s_transfer { - t_vec string; - int bits_written; + int bit; int transfer_done; -} t_transfer; +} t_transfer; t_transfer g_transfer; -void signal_bit_decoder(int signum) +void bit_reciever(int signum) { - const char null_char = 0; - - if (g_transfer.bits_written == 0) - ft_vec_append(&g_transfer.string, &null_char); if (signum == SIGUSR1) - *(char *)ft_vec_access(&g_transfer.string, g_transfer.string.size - 1) |= 1 << g_transfer.bits_written; - ++g_transfer.bits_written; - g_transfer.transfer_done = (g_transfer.bits_written == CHAR_BIT && !(*(char *)ft_vec_access(&g_transfer.string, g_transfer.string.size - 1))); - g_transfer.bits_written %= CHAR_BIT; + g_transfer.bit = 1; + else + g_transfer.bit = 0; + g_transfer.transfer_done = 1; return ; } @@ -46,15 +41,21 @@ void setup_handler(void) sigemptyset(&sa.sa_mask); sigaddset(&sa.sa_mask, SIGUSR1); sigaddset(&sa.sa_mask, SIGUSR2); - sa.sa_handler = signal_bit_decoder; + sa.sa_handler = bit_reciever; sigaction(SIGUSR1, &sa, NULL); sigaction(SIGUSR2, &sa, NULL); return ; } -int main(void) +void init_transfer(t_transfer *t) { - ft_vec_init(&g_transfer.string, sizeof(char)); + t->transfer_done = 0; + return ; +} + +void general_setup(t_transfer *t) +{ + init_transfer(t); setup_handler(); ft_printf("Hello, I'm a minitalk server.\n" "You can contact me through my PID: %i.\n" @@ -62,16 +63,61 @@ int main(void) "after this initial message.\n" "I'll also append newline to every message recieved.\n" "I'm starting to print the messages now:\n\n", getpid()); + return ; +} + +int main(void) +{ + pid_t c_pid; + int c_pid_known; + int bits_recieved; + char ch; + t_vec string; + + bits_recieved = 0; + c_pid = 0; + c_pid_known = 0; + ch = 0; + general_setup(&g_transfer); + ft_vec_init(&string, sizeof(char)); while (1) { - pause(); - if (g_transfer.transfer_done) + if (c_pid_known) + kill(c_pid, SIGUSR1); + if (!g_transfer.transfer_done) + pause(); + if (g_transfer.transfer_done && !c_pid_known) + { + c_pid |= g_transfer.bit << bits_recieved; + g_transfer.transfer_done = 0; + ++bits_recieved; + if (bits_recieved == sizeof(pid_t) * CHAR_BIT) + { + bits_recieved = 0; + c_pid_known = 1; + } + } + else if (g_transfer.transfer_done) { - ft_printf(g_transfer.string.vec); - ft_printf("\n"); - ft_vec_forget_range(&g_transfer.string, g_transfer.string.size, 0); + ch |= g_transfer.bit << bits_recieved; g_transfer.transfer_done = 0; + ++bits_recieved; + if (bits_recieved == CHAR_BIT && ch != 0) + { + ft_vec_append(&string, &ch); + } + else if (bits_recieved == CHAR_BIT && ch == 0) + { + ft_printf("From process %i: %s\n", c_pid, string.vec); + ft_vec_forget_range(&string, string.size, 0); + c_pid_known = 0; + c_pid = 0; + } + bits_recieved %= CHAR_BIT; + if (bits_recieved == 0) + ch = 0; } } + ft_vec_free(&string, NULL); return (0); } -- 2.30.2