Rework communication protocol
authorLukas Jiriste <ljiriste@student.42prague.com>
Tue, 23 Jan 2024 11:36:32 +0000 (12:36 +0100)
committerLukas Jiriste <ljiriste@student.42prague.com>
Tue, 23 Jan 2024 11:36:32 +0000 (12:36 +0100)
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
src/server.c

index c9e2a37e9ef90339a7862051337bf82fb4a0bab4..e6c4f37a0133c3311b8cedc981effabf92a0a20d 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include <signal.h>
 #include <unistd.h>
 
-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);
 }
index cc4aa65ce93c49b423ddd33bc0e4e63401400369..16615333087a215919238c14589f553780c1a2fd 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   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       */
 /*                                                                            */
 /* ************************************************************************** */
 
 
 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);
 }