我想創建一個命名管道(FIFO)的簡單例子。在這裏,服務器將監聽來自客戶端的消息,該消息寫在命名管道上,這兩者通用。要實施的特殊事項是FIFO應該是非阻塞的(使用O_NONBLOCK
)。Linux:創建一個簡單的非阻塞服務器和客戶端通過命名管道進行通信
通過非阻塞,我的意思是作者應該在寫完後立即返回,如果沒有讀者的話。同樣,如果沒有消息(沒有作者),讀者應該立即返回。
我已經創建了阻塞版本,雖然它的工作正常。然後我試圖將其轉換爲非阻塞。
這裏的客戶端:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#define FIFO "/tmp/myFIFO"
/*
This acts as the client, writing to the FIFO
*/
int main(int argc, char *argv[])
{
FILE *fp;
int fifo_fd;
if(argc != 2)
{
printf("Usage : ./fifo_client <message> \n");
exit(1);
}
fifo_fd = open(FIFO, O_WRONLY | O_NONBLOCK);
if(fifo_fd < 0)
{
perror("Error while open call");
exit(1);
}
fp = fdopen(fifo_fd, "w");
if(fp == NULL)
{
perror("Error while opening fd");
exit(1);
}
fputs(argv[1],fp);
/* Close the fp */
fclose(fp);
return 0;
}
這裏的服務器:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define FIFO "/tmp/myFIFO"
/*
This acts as a server waiting for strings to be written by the client, over the FIFO
*/
int main()
{
FILE *fp;
int fifo_fd;
char buf[1024];
/* Create a FIFO */
umask(0);
if(mkfifo(FIFO,0666) < 0) /* 0666 is read and write permission*/
{
perror("Error creating FIFO");
exit(1);
}
while(1) /*endless wait, keep reading strings and print*/
{
fifo_fd = open(FIFO, O_RDONLY | O_NONBLOCK);
if(fifo_fd < 0)
{
perror("Error while open call");
exit(1);
}
fp = fdopen(fifo_fd, "w");
if(fp == NULL)
{
perror("Error while opening fd");
exit(1);
}
if(!fgets(buf,1024,fp))
printf("Nothing to read\n");
else
printf("Message Recieved : %s\n", buf);
fclose(fp);
sleep(1);
}
return 0;
}
我第一次運行該服務器。
其次,第二終端上,當我運行客戶端,我得到的錯誤:
Error while open call: No such device or address
我缺少什麼?我做了man
,參數看起來是正確的。
編輯
移動open
和close
召喚出while循環的,做的工作。但是,現在如果客戶端不啓動服務器啓動,引發以下錯誤:
錯誤而公開呼籲:沒有這樣的設備或地址
文件/tmp/myFIFO
存在文件系統從服務器的前一次執行,必須由客戶使用。
(與您的問題無關的評論)。如果調用沒有參數的程序來獲得使用語句不是錯誤,你應該'退出0'。如果出現錯誤,您應該將使用說明打印到stderr。 'perror(FIFO)'比'perror(「創建FIFO的錯誤)'更有用。用戶希望在錯誤消息中看到文件的名稱。 –
您不檢查由fgets和fputs返回的錯誤,這意味着您不在乎它們是否成功。爲什麼抱怨你的程序無法正常工作? –
您的服務器重複打印顯示它不是*阻塞。您沒有收到提示,因爲服務器沒有完成。 –