Reputation: 21
I had a task from school in which I need to write a client that will send string using signals (only SIGUSR1 as 1 or SIGUSR2 as 0) to server, which then should display this string. The problem is that server can normally handle only a little amount of symbols. In other cases it pauses with client or just shows weird symbols. I've tried to write in different ways using global variable in client for confirmation from server (with and without pausing the client), using usleep()
(100/600/1000/10000), using pause()
, result is always the same as when I fast call client again and again.
I'm writing it using VirtualBox Ubuntu.
UPD: Problem solved using sleep (5)
instead of pause()
in client and increasing usleep()
up to 1000
Client:
#include "minitalk.h"
int g_recieve;
void sending_bits(char c, int pid)
{
int i;
i = 128;
while(i >= 1)
{
if (g_recieve == 1)
{
if (i & c)
{
if (kill(pid, SIGUSR1) == -1)
errors("Error in sending signal!\n");
}
else
{
if (kill(pid, SIGUSR2) == -1)
errors("Error in sending signal!\n");
}
i /= 2;
g_recieve = 0;
}
//usleep(600);
}
}
int send_str(int pid, char *s)
{
int i;
i = 0;
while (s[i])
{
sending_bits(s[i], pid);
i++;
}
return (0);
}
void cl_handler(int signum, siginfo_t *siginfo, void *context)
{
(void)context;
(void)siginfo;
(void)signum;
g_recieve = 1;
write(1, "Recieved signal from server\n", 28);
return ;
}
int main(int argc, char **argv)
{
struct sigaction sigac;
g_recieve = 1;
sigemptyset(&sigac.sa_mask);
sigaddset(&sigac.sa_mask, SIGINT);
sigaddset(&sigac.sa_mask, SIGQUIT);
sigaddset(&sigac.sa_mask, SIGUSR1);
sigac.sa_flags = SA_SIGINFO;
sigac.sa_sigaction = cl_handler;
if (sigaction(SIGUSR2, &sigac, NULL) == -1)
errors("Error in client sigaction\n");
if (ft_atoi(argv[1]) < 0)
errors("Wrong PID!\n");
if (argc == 3)
send_str(ft_atoi(argv[1]), argv[2]);
else
errors("Wrong arguments!\n");
while (1)
pause ();
return (0);
}
Server:
#include "minitalk.h"
void sv_handler(int signum, siginfo_t *siginfo, void *unused)
{
static int ascii = 0;
static int power = 0;
(void)unused;
if (signum == SIGUSR1)
ascii += (128 >> power);
power += 1;
if (power == 8)
{
ft_putchar(ascii);
power = 0;
ascii = 0;
}
if (siginfo->si_pid == 0)
errors("Server didn't get client's PID\n");
if (kill(siginfo->si_pid, SIGUSR2) == -1)
errors("Error in returning signal!\n");
}
int main(int argc, char **argv)
{
struct sigaction sigac;
(void)argv;
if (argc != 1)
errors("Error arguments\n");
write(1, "Server started!\nPID: ", 21);
ft_putnbr(getpid());
write(1, "\n", 1);
sigemptyset(&sigac.sa_mask);
//sigaddset(&sigac.sa_mask, SIGINT);
//sigaddset(&sigac.sa_mask, SIGQUIT);
sigac.sa_flags = SA_SIGINFO;
sigac.sa_sigaction = sv_handler;
if ((sigaction(SIGUSR1, &sigac, 0)) == -1)
errors("Error sigaction\n");
if ((sigaction(SIGUSR2, &sigac, 0)) == -1)
errors("Error sigaction\n");
while (1)
pause();
return (0);
}
Upvotes: 2
Views: 1098
Reputation: 21
Problem solved using sleep(5)
instead of pause()
in client and increasing usleep()
in client up to 1000.
Upvotes: 0