【发布时间】:2021-07-10 22:36:45
【问题描述】:
我正在尝试编写一个程序,使用服务器和客户端这两个进程来模拟服务器和客户端之间的通信:
我们将首先启动服务器,然后启动客户端(带有参数./client [SERVER PID] [Message]),我被允许仅使用 UNIX 信号向服务器发送字符串消息,所以我使用两个信号 SIGUSR1 和 SIGUSR2以二进制形式发送字符的值,然后在服务器中将其转换回 char 并显示:所以这是我客户端的代码:
#include <minitalk_client.h>
void send_message_to_server(pid_t ppid, const unsigned char *msg)
{
unsigned char mask;
int i;
ft_putstr("Sending message `");
ft_putstr((const char *)msg);
ft_putstr("` to server: ");
ft_putnbr(ppid);
ft_putchar('\n');
while (*msg)
{
mask = 1 << 7;
while (mask)
{
if (*msg & mask)
kill(ppid, SIGUSR1);
else
kill(ppid, SIGUSR2);
usleep(300);
mask >>= 1;
}
msg++;
}
i = -1;
while (++i < 8)
{
kill(ppid, SIGUSR2);
usleep(300);
}
}
int main(int argc, char **argv)
{
int ppid;
if (argc != 3)
{
write(2, "Invalid arguments\n", 18);
return (1);
}
ppid = ft_atoi(argv[1]);
send_message_to_server(ppid, (const unsigned char *)argv[2]);
return (0);
}
和服务器:
#include <minitalk_server.h>
void sig_handler(int sig)
{
static unsigned char character;
static unsigned char mask = 1 << 7;
static bool is_new_message = true;
if (is_new_message)
{
ft_putstr("Received message from client: ");
is_new_message = false;
}
if (sig == SIGUSR1)
character |= mask;
mask >>= 1;
if (!mask)
{
if (character)
ft_putchar(character);
else
{
ft_putchar('\n');
is_new_message = true;
}
character = 0;
mask = 1 << 7;
}
}
int main(void)
{
struct sigaction act;
const pid_t pid = getpid();
sigemptyset(&act.sa_mask);
act.sa_handler = sig_handler;
sigaction(SIGUSR1, &act, 0);
sigaction(SIGUSR2, &act, 0);
ft_putstr("Started minitalk server with pid: ");
ft_putnbr(pid);
ft_putchar('\n');
while (1)
pause();
return (0);
}
所以我的代码有效,但是当我没有等待足够的时间时,sleep 出现问题,一些信号没有被捕获,它会执行以下操作:
Suspendisse consectetur consequaa�@������\@����@����@��������@�����\@��������@������@����@��@���������@������\@�����@���@������@���������X
我不想等待太多,因为这会使我的程序太慢,所以有没有办法将信号放入“队列”中,这样当我想在一个循环中发送多个信号时,就不需要了在每个人之间等待?
(我知道信号不是最好的方法,但这是一个学校项目,我只能这样做)
【问题讨论】:
-
有些信号可以排队,但 SIGUSR1 和 SIGUSR2 不在其中。选择信号有什么灵活性?如果这是家庭作业,请编辑您的问题以包含任何限制条件,以便我们避开您无法使用的建议。
-
信号是错误的机制——你想使用管道或套接字
-
@Mark Plotnick 确实是一个学校项目,我只能使用 SIGUSR1 和 SIGUSR2 在进程之间进行通信