[英]I can't understand the result of this chatting program
所以我做了一個簡單的服務器-客戶端程序,可以使用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 This is client
留言
向服務器發送消息..
消息已發送
輸入您要發送的內容:msgtaken
向服務器發送消息..
消息已發送
輸入您要發送的內容:msgtaken
向服務器發送消息..
消息已發送
輸入您要發送的內容:msgtaken
向服務器發送消息..
消息已發送
輸入您要發送的內容:msgtaken
向服務器發送消息..
消息已發送
輸入您要發送的內容:
那是因為它是這樣接受輸入的:
scanf(" %s", msg);
我們來看看scanf
的文檔(重點是我的):
s:任意數量的非空白字符,在找到的第一個空白字符處停止。 在存儲序列的末尾自動添加終止空字符。
這就是為什么當您發送Hello Server this is client
時它在Hello
之后停止的原因。 還要注意" %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);
每個示例,這意味着對於 100 的緩沖區大小,只能讀入 99 個char
,加上一個空終止符。這樣您就可以避免如果用戶輸入的字符串對於您來說太大而不會發生未定義的行為緩沖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.