2

我有一个学校的任务,我需要编写一个客户端,它将使用信号(仅 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);
}
4

1 回答 1

0

使用sleep(5)而不是pause()在客户端中解决了问题,并且usleep()在客户端中增加到 1000。

于 2021-11-21T14:28:03.533 回答