简体   繁体   English

我无法理解这个聊天程序的结果

[英]I can't understand the result of this chatting program

So I made a simple server-client program that can communicate with each other using fifo file (msgfifo).所以我做了一个简单的服务器-客户端程序,可以使用fifo文件(msgfifo)相互通信。

My question is: When I type a message which includes a space, the receiver process runs several times with number of words.我的问题是:当我键入一条包含空格的消息时,接收器进程会以字数运行多次。

That's not I expected, as I expected to print it out as a whole sentence, but it doesn't, and I want to know why.这不是我所期望的,因为我希望将它作为一个完整的句子打印出来,但事实并非如此,我想知道为什么。

When I type a something to send, process send SIGUSR1 signal to another.当我输入要发送的内容时,进程会向另一个发送 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");
}

Expected:预期的:

Client : Hello Server this is client客户端:你好服务器这是客户端

Actual: /* server */实际:/* 服务器 */


Incoming Message from client...来自客户端的传入消息...
Hello你好
Incoming Message from client...来自客户端的传入消息...
this这个
Incoming Message from client...来自客户端的传入消息...
is
Incoming Message from client...来自客户端的传入消息...
client客户

Type what u want to send :输入您要发送的内容:

/ client / /客户/


Type what u want to send : Hello Server This is client输入您要发送的内容:Hello Server This is client
msgtaken留言
Send message to server..向服务器发送消息..
Message sent消息已发送

Type what u want to send : msgtaken输入您要发送的内容:msgtaken
Send message to server..向服务器发送消息..
Message sent消息已发送

Type what u want to send : msgtaken输入您要发送的内容:msgtaken
Send message to server..向服务器发送消息..
Message sent消息已发送

Type what u want to send : msgtaken输入您要发送的内容:msgtaken
Send message to server..向服务器发送消息..
Message sent消息已发送

Type what u want to send : msgtaken输入您要发送的内容:msgtaken
Send message to server..向服务器发送消息..
Message sent消息已发送


Type what u want to send :输入您要发送的内容:

That's because this is how it takes input:那是因为它是这样接受输入的:

scanf(" %s", msg);

Let's have a look at the documentation of scanf (emphasis mine):我们来看看scanf的文档(重点是我的):

s: Any number of non-whitespace characters, stopping at the first whitespace character found . s:任意数量的非空白字符,在找到的第一个空白字符处停止 A terminating null character is automatically added at the end of the stored sequence.在存储序列的末尾自动添加终止空字符。

That's why it stops after Hello when you send Hello Server this is client .这就是为什么当您发送Hello Server this is client时它在Hello之后停止的原因。 Also note the space in " %s" , this means that it will also ignore any whitespace at the start of the input.还要注意" %s"的空格,这意味着它也将忽略输入开头的任何空格。 So when it reads the Server on the next run through the loop, this makes it ignore the space between Hello and Server .因此,当它在下一次循环中读取Server时,这使它忽略了HelloServer之间的空间。 As a result, it goes through the loop five times, and the messages each time are Hello , Server , this , is and client .结果,它循环了五次,每次的消息都是Hello , Server , this , isclient

Instead, you could use getline :相反,您可以使用getline

char *message = NULL;
size_t length;
getline(&message, &length, stdin);
// use message
free(message);

A little side note: to make your scanf call more safe, you can specify a maximum size for the string input:小提示:为了使您的scanf调用更安全,您可以指定字符串输入的最大大小:

scanf(" %99s", msg);

Per example, this would mean that only 99 char can be read in, plus a null terminator, for a buffer size of 100. This way you can avoid undefined behavior that would occur if the user would enter a string that is too big for your buffer.每个示例,这意味着对于 100 的缓冲区大小,只能读入 99 个char ,加上一个空终止符。这样您就可以避免如果用户输入的字符串对于您来说太大而不会发生未定义的行为缓冲。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM