我有一个学校的任务,我需要编写一个客户端,它将使用信号(仅 SIGUSR1 作为 1 或 SIGUSR2 作为 0)向服务器发送字符串,然后服务器应该显示这个字符串。问题是服务器通常只能处理少量的符号。在其他情况下,它会在客户端暂停或仅显示奇怪的符号。我尝试使用客户端中的全局变量以不同方式编写以从服务器确认(有和没有暂停客户端),使用usleep()
(100/600/1000/10000),使用pause()
,结果总是与我快速调用时相同客户一次又一次。
我正在使用 VirtualBox Ubuntu 编写它。
UPD:sleep (5)
使用而不是pause()
在客户端解决问题并增加到usleep()
1000
客户:
#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);
}
服务器:
#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);
}