[英]Need to have non-blocking named pipes capable of two way communication in c on Linux
[英]Linux : Creating a simple non-blocking server and client to communicate over named pipes
我正在嘗試創建一個命名管道(FIFO)的簡單示例。 在這里,服務器將偵聽來自客戶端的消息,該消息將在雙方共同的命名管道上寫入。 要實現的特殊之處在於,FIFO應該是非阻塞的(使用O_NONBLOCK
)。
所謂非阻塞,是指如果沒有讀者,作家應該在寫作后立即返回。 同樣,如果沒有消息(沒有作者),則讀者應立即返回。
我已經創建了阻止版本,並且可以正常工作。 然后,我試圖將其轉換為非阻塞。
這是客戶:
#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
文件存在於服務器先前執行的文件系統上,必須由客戶端使用。
主要問題是循環打開和關閉文件。 這是沒有道理的。 打開和關閉之間的時間間隔很短,您的客戶必須按此間隔。 這樣做的機會很小。 出現“沒有這樣的設備或地址”消息的確切原因是客戶端錯過了打開文件的瞬間。 這是主要問題。 嘗試將open
, fopen
和fclose
移出服務器循環。
您也可以open
閱讀,但可以fopen
寫作,但是我想這只是一個錯字。 此組合將無法運行。 您需要將fopen
的模式更改為"r"
。
還有其他較小的問題。
open
,但有時打開會成功而寫入會失敗。 stdio
用於管道幾乎沒有意義。 read
和write
會做就好了。 最后但並非最不重要的一點是, sleep
表明存在設計問題。 確實,在該程序中,阻塞I / O更有意義。 如果您只想嘗試非阻塞I / O,則可以使用sleep
,但是在實際程序中應避免使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.