因此,我制作了一个简单的服务器-客户端程序,可以使用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
发送 消息发送到服务器。
消息发送
键入您要发送的内容 :msgtaken
将消息发送到服务器。
消息已发送
类型 您要发送的内容:msgtaken
发送消息到服务器。
消息已发送
输入您要发送的内容:
答案 0 :(得分:1)
这是因为这是输入的方式:
scanf(" %s", msg);
让我们看看scanf
(重点是我的)的文档:
s:任意数量的非空白字符,在第一个字符处停止 找到空格字符。终止的空字符是 自动添加到存储序列的末尾。
这就是为什么在发送Hello
时它会在Hello Server this is client
之后停止的原因。还要注意" %s"
中的空格,这意味着它也会在输入开始时忽略任何空格。因此,当它在下一次遍历循环时读取Server
时,将使其忽略Hello
和Server
之间的空格。结果,它经历了五次循环,并且每次的消息分别为Hello
,Server
,this
,is
和client
。>
相反,您可以使用getline
:
char *message = NULL;
size_t length;
getline(&message, &length, stdin);
// use message
free(message);
注意一点:为了使您的scanf
通话更加安全,您可以为字符串输入指定最大大小:
scanf(" %99s", msg);
每个示例,这意味着只能读取99 char
,再加上一个空终止符,缓冲区大小为100。这样,您可以避免如果用户输入以下内容会发生未定义的行为:对于缓冲区来说太大的字符串。