??
字號:
/*************************************************************
* 用FIFO實現進程間通信的例子example2-03.c example2-04.c
************************************************************/
/*******************************************************************************************
* 因為FIFO不要求進程間有親緣關系,服務器端就可以以眾所周知的路徑名創建一個FIFO,并打開來讀。
* 此后,另外的客戶進程就可以打開該FIFO來寫,將消息通過FIFO傳給服務器。但這只是一種單向的數據
* 傳送,要實現雙向的數據傳送,可以每個客戶進程在創建一個FIFO(可以用自己的進程ID來命名),
* 從而在實現從服務器到客戶端的通信。
*******************************************************************************************/
/*******************************************************************************************
* 此例中客戶端向服務器端發送一個路徑名,服務器端去打開客戶所請求的文件并返回文件內容,客戶收
* 到回應后將文件內容打印到標準輸出。服務器以路徑名/tmp/fifo.serv來創建FIFO,并從此FIFO中讀出
* 客戶請求。而客戶端都創建自己的FIFO,路徑名以自己的進程號來標識。然后將自己的請求寫入服務器
* 創建的FIFO中,二次請求中包含它的進程號和請求的路徑名。服務器據此將相應的文件內容寫回到該進
* 程創建的FIFO中,從而實現雙向通信。
*******************************************************************************************/
/*****************************************
* 服務器端程序example2-03.c
*****************************************/
/***************************************************************************************************
第53、54行兩次用open()打開此FIFO文件,一次只讀,一次只寫。而第二次打開后獲得的描述符從未使用。
這是因為,若只打開一次,那么每當一個客戶終止時,該FIFO就會變空,服務器的read也會返回0,表示文件結束。
這樣,就只能關閉次FIFO,然后再次調用read。但是這次會阻塞調用,直到下一個客戶請求到為止。
如果總是有一個文件描述符被打開進行寫操作,那么read函數就不會返回,而是一直阻塞直到有客戶請求為止。
***************************************************************************************************/
#include <SYS types.h>
#include <SYS stat.h>
#include <FCNTL.H>
#include <ERRNO.H>
#include <STDIO.H>
#include <STDLIB.H>
#define SERV_FIFO "/tmp/fifo.serv"
#define LINE 1024
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
int main()
{
int readf, writef, dummyfd, fd;
char *ptr, buff[LINE], fifoname[LINE];
pid_t pid; //進程標識符
ssize_t n;
/* create fifo use wellknow pathname */
if (((mkfifo(SERV_FIFO, FILE_MODE)<0) && (errno != EEXIST))) //未產生文件或文件不存在,則
printf("can't create fifo");
readf = open(SERV_FIFO, O_RDONLY, 0); /* open the fifo with read only mode */
dummyfd = open(SERV_FIFO, O_WRONLY, 0); /* open the fifo with write only mode */
while ((n = getline(buff, 100, readf)) > 0) {
if (buff[n-1] == '\n')
n--; /* delete the return character */
buff[n] = '\0'; /* end the pathname with null character */
if ((ptr = strchr(buff, ' ')) == NULL) {
printf("bogus request: %s", buff);
continue;
}
*ptr++ = 0;
pid = atoi(buff);
/* create the pathname of the client's fifo */
snprintf(fifoname, sizeof(fifoname), "/tmp/fifo.%ld", (long)pid);
if ((writef = open(fifoname, O_WRONLY, 0)) < 0) {
printf("cannot open: %s", fifoname);
continue;
}
if ((fd = open(ptr, O_WRONLY)) < 0) {
snprintf(buff + n, sizeof(buff) - n, ": can't open, %s\n",strerror(errno));
n = strlen(ptr);
write(writef, ptr, n); /* write the file to the client's fifo */
close(writef);
}
else {
while ((n = read(fd, buff, LINE)) > 0)
write(writef, buff, n);
close(fd);
close(writef);
}
}
exit(0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -