├── Makefile ├── README.md ├── clients ├── client.c ├── client.h └── utils.c ├── screenshots ├── send_signal_1.png ├── send_signal_2.png ├── send_signal_3.png └── signals.jpg └── servers ├── server.c ├── server.h └── utils.c /Makefile: -------------------------------------------------------------------------------- 1 | NAME = client 2 | NAME2 = server 3 | 4 | FUNCTIONS = ./clients/client \ 5 | ./clients/utils 6 | 7 | FUNC = ./servers/server \ 8 | ./servers/utils 9 | 10 | FLAGS = -Wall -Wextra -Werror 11 | 12 | SRC = $(addsuffix .c, $(FUNCTIONS)) 13 | EXCH = $(addsuffix .o, $(FUNCTIONS)) 14 | 15 | SRC2 = $(addsuffix .c, $(FUNC)) 16 | EXCH2 = $(addsuffix .o, $(FUNC)) 17 | 18 | all: $(NAME) $(NAME2) 19 | 20 | $(NAME): $(EXCH) 21 | gcc $(FLAGS) $(EXCH) -o $(NAME) 22 | 23 | $(NAME2): $(EXCH2) 24 | gcc $(FLAGS) $(EXCH2) -o $(NAME2) 25 | 26 | %.o: %.c 27 | gcc $(FLAGS) -o $@ -c $< 28 | 29 | clean: 30 | /bin/rm -f ./clients/*.o 31 | /bin/rm -f ./servers/*.o 32 | 33 | fclean: clean 34 | /bin/rm -f $(NAME) $(NAME2) 35 | 36 | re: fclean all -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Screen](https://raw.githubusercontent.com/atomatoe/minitalk/master/screenshots/signals.jpg) 2 | 3 | ________________________________________________________________ 4 | 5 | ####

"Это реально ненормальное программирование! :)"

#### 6 | ________________________________________________________________ 7 | 8 | 9 | ### Цель проекта: 10 | Реализовать связь между двумя процессами Client и Server посредством сигналов в С, по стандарту 98 года. 11 |

В виде связи выступает передача строки от одного процесса к другому.

12 | 13 | ### Реализация: 14 |

Текущий процесс приостанавливается (pause) и в нем работает обработчик сигнала, который срабатывает при получении сигнала (func my_handler).

15 |

Будем отправлять строку посредством сигналов sigusr1 и sigusr2. Один символ - отправка 8 сигналов.

16 |

Каждый сигнал будет отправлен в виде 0 или 1, символ будет переведен в ASCII код и далее в двоичную систему счисления.

17 |

Использовать будем сигналы sigusr1, означающий 1, и sigusr2, означающий 0.

18 |

Двоичная система счисления имеет 8 байт, следовательно server будет знать, что каждые 8 сигналов - это один символ. В таком случае нужно обратить внимание, что некоторые алгоритмы конвертации dec2bin отсеивают ведущие нули. Если запрос придет меньше 8 сигналов - сервер не обработает его.

19 |

Как только сервер принимает запрос (т.е один символ), он его переводит bin2dec и выводит на экран. Таким образом отсылается и выводится вся строка.

20 | 21 | ### Стек технологий: 22 | * С 23 | * Signals 24 | 25 | ________________________________________________________________ 26 | 27 | 28 |
29 | Screenshots 30 | 31 | ________________________________________________________________ 32 | 33 |

Ссылка

34 |

Ссылка

35 |

Ссылка

36 | ________________________________________________________________ 37 | 38 |
39 | 40 |
41 | Полезная информация и ссылки 42 |

43 |

Обработка сигналов занимает некоторое время, и если вы посылаете слишком много за один раз, некоторые из них могут быть проигнорированы. Именно поэтому я использую usleep.

44 |

Printf нельзя вызывать внутри сигнала. Именно из-за printf не мог понять почему server не принимал сигнал. Советую не использовать его в момент написания проекта или его тестирования.

45 |

Подробнее о SIGUSR1 и SIGUSR2

47 |

Передача файлов сигналами

48 |

Как узнать завершился ли процесс-потомок?

49 |

Список разрешенных функций внутри обработчика сигнала

50 | 51 |
52 | 53 | 54 | 55 |
56 | bin2dec и dec2bin 57 | 58 | ```C 59 | int bin2dec(int n) 60 | { 61 | int num; 62 | int dec_value; 63 | int base; 64 | int temp; 65 | int last_digit; 66 | 67 | num = n; 68 | base = 1; 69 | dec_value = 0; 70 | temp = num; 71 | while (temp) 72 | { 73 | last_digit = temp % 10; 74 | temp = temp / 10; 75 | dec_value += last_digit * base; 76 | base = base * 2; 77 | } 78 | return dec_value; 79 | } 80 | 81 | int dec2bin(int server_pid, int num) 82 | { 83 | int bin = 0; 84 | int k = 1; 85 | int i = 0; 86 | 87 | while (num) 88 | { 89 | bin += (num % 2) * k; 90 | k *= 10; 91 | num /= 2; 92 | i++; 93 | } 94 | return bin; 95 | } 96 | ``` 97 | 98 |
99 | 100 | ### Если я помог как-то вам, то буду благодарен за звездочку :) 101 | 102 | -------------------------------------------------------------------------------- /clients/client.c: -------------------------------------------------------------------------------- 1 | // by atomatoe 2 | 3 | #include "client.h" 4 | 5 | void decimal_conversion(char ascii, int power, int pid) 6 | { 7 | if (power > 0) 8 | decimal_conversion(ascii / 2, power - 1, pid); 9 | if ((ascii % 2) == 1) 10 | { 11 | if (kill(pid, SIGUSR1) == -1) 12 | { 13 | ft_putstr("Error signal!\n"); 14 | exit(0); 15 | } 16 | } 17 | else 18 | { 19 | if (kill(pid, SIGUSR2) == -1) 20 | { 21 | ft_putstr("Error signal!\n"); 22 | exit(0); 23 | } 24 | } 25 | usleep(100); 26 | } 27 | 28 | int send_message(int server_pid, char *msg) 29 | { 30 | int i; 31 | 32 | i = 0; 33 | while (msg[i] != '\0') 34 | { 35 | decimal_conversion(msg[i], 7, server_pid); 36 | i++; 37 | } 38 | return (0); 39 | } 40 | 41 | void my_handler(int signum, siginfo_t *siginfo, void *unused) 42 | { 43 | (void)unused; 44 | (void)siginfo; 45 | (void)signum; 46 | ft_putstr("Signal received\n"); 47 | } 48 | 49 | int main(int argc, char **argv) 50 | { 51 | struct sigaction catch; 52 | 53 | catch.sa_flags = SA_SIGINFO; 54 | catch.sa_sigaction = my_handler; 55 | if ((sigaction(SIGUSR2, &catch, 0)) == -1) 56 | error("Error sigaction\n"); 57 | if (argc == 3) 58 | send_message(atoi(argv[1]), argv[2]); 59 | else 60 | error("Error arguments\n"); 61 | while (1) 62 | pause(); 63 | return (0); 64 | } 65 | -------------------------------------------------------------------------------- /clients/client.h: -------------------------------------------------------------------------------- 1 | // by atomatoe 2 | 3 | #ifndef CLIENT_H 4 | # define CLIENT_H 5 | 6 | # include 7 | # include 8 | # include 9 | 10 | void ft_putstr(char *str); 11 | void error(char *str); 12 | void decimal_conversion(char ascii, int power, int pid); 13 | int send_message(int server_pid, char *msg); 14 | void my_handler(int signum, siginfo_t *siginfo, void *unused); 15 | 16 | #endif -------------------------------------------------------------------------------- /clients/utils.c: -------------------------------------------------------------------------------- 1 | // by atomatoe 2 | 3 | #include "client.h" 4 | 5 | void ft_putstr(char *str) 6 | { 7 | int i; 8 | 9 | i = 0; 10 | while (str[i]) 11 | { 12 | write(1, &str[i], 1); 13 | i++; 14 | } 15 | } 16 | 17 | void error(char *str) 18 | { 19 | ft_putstr(str); 20 | exit(0); 21 | } 22 | -------------------------------------------------------------------------------- /screenshots/send_signal_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atomatoe/minitalk/d6035c26ee804bcbb67eabeca606f6cba804c0f1/screenshots/send_signal_1.png -------------------------------------------------------------------------------- /screenshots/send_signal_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atomatoe/minitalk/d6035c26ee804bcbb67eabeca606f6cba804c0f1/screenshots/send_signal_2.png -------------------------------------------------------------------------------- /screenshots/send_signal_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atomatoe/minitalk/d6035c26ee804bcbb67eabeca606f6cba804c0f1/screenshots/send_signal_3.png -------------------------------------------------------------------------------- /screenshots/signals.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atomatoe/minitalk/d6035c26ee804bcbb67eabeca606f6cba804c0f1/screenshots/signals.jpg -------------------------------------------------------------------------------- /servers/server.c: -------------------------------------------------------------------------------- 1 | // by atomatoe 2 | 3 | #include "server.h" 4 | 5 | void sig_to_str(int bin) 6 | { 7 | char c; 8 | int i; 9 | 10 | i = 0; 11 | c = '\0'; 12 | c += (bin << i++); 13 | if (i > 7) 14 | { 15 | if (c == '\0') 16 | ft_putchar('\n'); 17 | else 18 | ft_putchar(c); 19 | c = 0; 20 | i = 0; 21 | } 22 | } 23 | 24 | void my_handler(int signum, siginfo_t *siginfo, void *unused) 25 | { 26 | static int ascii = 0; 27 | static int power = 0; 28 | 29 | (void)unused; 30 | if (signum == SIGUSR1) 31 | ascii += 1 << (7 - power); 32 | power += 1; 33 | if (power == 8) 34 | { 35 | ft_putchar(ascii); 36 | power = 0; 37 | ascii = 0; 38 | if (kill(siginfo->si_pid, SIGUSR2) == -1) 39 | error("Error signal\n"); 40 | } 41 | } 42 | 43 | int main(int argc, char **argv) 44 | { 45 | struct sigaction catch; 46 | 47 | (void)argv; 48 | if (argc != 1) 49 | error("Error arguments\n"); 50 | write(1, "Server started!\nPID: ", 21); 51 | ft_putnbr(getpid()); 52 | write(1, "\n", 1); 53 | catch.sa_flags = SA_SIGINFO; 54 | catch.sa_sigaction = my_handler; 55 | if ((sigaction(SIGUSR1, &catch, 0)) == -1) 56 | error("Error sigaction\n"); 57 | if ((sigaction(SIGUSR2, &catch, 0)) == -1) 58 | error("Error sigaction\n"); 59 | while (1) 60 | pause(); 61 | return (0); 62 | } 63 | -------------------------------------------------------------------------------- /servers/server.h: -------------------------------------------------------------------------------- 1 | // by atomatoe 2 | 3 | #ifndef SERVER_H 4 | # define SERVER_H 5 | 6 | # include 7 | # include 8 | # include 9 | 10 | void ft_putstr(char *str); 11 | void error(char *str); 12 | void ft_putchar(char c); 13 | void ft_putnbr(int n); 14 | void sig_to_str(int bin); 15 | void my_handler(int signum, siginfo_t *siginfo, void *unused); 16 | 17 | #endif -------------------------------------------------------------------------------- /servers/utils.c: -------------------------------------------------------------------------------- 1 | // by atomatoe 2 | 3 | #include "server.h" 4 | 5 | void ft_putstr(char *str) 6 | { 7 | int i; 8 | 9 | i = 0; 10 | while (str[i]) 11 | { 12 | write(1, &str[i], 1); 13 | i++; 14 | } 15 | } 16 | 17 | void error(char *str) 18 | { 19 | ft_putstr(str); 20 | exit(0); 21 | } 22 | 23 | void ft_putchar(char c) 24 | { 25 | write(1, &c, 1); 26 | } 27 | 28 | void ft_putnbr(int n) 29 | { 30 | if (n < 10) 31 | { 32 | ft_putchar(n + '0'); 33 | return ; 34 | } 35 | ft_putnbr(n / 10); 36 | ft_putchar((n % 10) + '0'); 37 | } 38 | --------------------------------------------------------------------------------