所以我制作了一个简单的服务器客户端程序,可以使用fifo文件(msgfifo)相互通信。
我的问题是:当我键入一条包含空格的消息时,接收方进程会用单词数运行多次。
这不是我所期望的,因为我期望把它作为一个完整的句子打印出来,但它没有,我想知道为什么。
当我键入要发送的内容时,处理将SIGUSR1信号发送到另一个。

/* receive msg part */
/* added this using sigset(SIGUSR1, receiveSIGUSR1) */

void receiveSIGUSR1()
{
    char* msg = "\nIncoming Message from client...";
    char* msg2 = "\nClient : ";
    char buf[max_of_msg];
    int fd;
    write(1, msg, strlen(msg)+1);
    fflush(stdin);
    if( (fd = open("./msgpipe", O_RDONLY)) < 0)
    {   perror("open"); exit(1);    }
    read(fd, buf, max_of_msg);
    close(fd);
    write(1, msg2, strlen(msg2)+1);
    write(1, buf, strlen(buf)+1);
    flag = 0;
}

/*send msg part*/

while(1)
{
    flag = -1;
    printf("\nType what u want to send : ");
    scanf(" %s", msg);
    if(flag == 0)   continue;
    printf("msgtaken\n");
    fflush(stdin);
    if( (fd = open("./msgpipe", O_RDWR)) < 0)
    {   perror("exit"); exit(1);    }
    kill(clpid, 30);
    sleep(2);
    printf("Send message to Client..\n");
    write(fd, msg, max_of_msg);
    printf("Message Sent...\n");
}

预期:
客户机:你好,服务器,这是客户机
实际:
/*服务器*/
来自客户端的传入消息。。。喂,收到消息
从客户端。。。来自客户端的此传入消息。。。是
来自客户端的传入消息。。。客户机类型
要发送:
/客户/
键入要发送的内容:Hello Server这是客户端
msgtaken将邮件发送到服务器。。已发送消息
键入要发送的内容:msgtaken将邮件发送到服务器。。
消息发送类型要发送的内容:msgtaken send
发送到服务器的邮件。。消息发送类型要发送的内容
:msgtaken将邮件发送到服务器。。消息发送类型
要发送的内容:msgtaken将邮件发送到服务器。。
消息发送
键入要发送的内容:

最佳答案

这是因为这就是它接受输入的方式:

scanf(" %s", msg);

让我们看看scanf的文档(重点是我的文档):
s:任意数量的非空白字符,在第一个字符处停止
找到空白字符。终止的空字符是
在存储序列的末尾自动添加。
这就是为什么当您发送Hello时它会在Hello Server this is client之后停止。还要注意" %s"中的空格,这意味着它还将忽略输入开头的任何空格。因此,当它在下一次遍历循环时读取Server时,这会使它忽略HelloServer之间的空间。结果,它会循环5次,每次的消息都是HelloServerthisisclientgetline
相反,您可以使用scanf
char *message = NULL;
size_t length;
getline(&message, &length, stdin);
// use message
free(message);

一点小提示:为了使您的调用更安全,您可以指定字符串输入的最大大小:
scanf(" %99s", msg);

在每个示例中,这意味着对于100的缓冲区大小,只能读入99char,外加一个空终止符。这样,您就可以避免在用户输入的字符串对于缓冲区来说太大时发生未定义的行为。

关于c - 我不明白这个聊天程序的结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56793025/

10-12 19:27