服務器端的原始碼如下:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<errno.h>
#include<stdlib.h>
#include<fcntl.h>
#include"fifo.h"
void server(int,int);
int main(int argc,char** argv)
{
int readfd,writefd;
//創建兩個FIFO(有名管道)
if((mkfifo(FIFO1,FILE_MODE) < 0) && (errno != EEXIST))
{
perror("mkfifo");
unlink(FIFO1);
exit(EXIT_FAILURE);
}
if((mkfifo(FIFO2,FILE_MODE) < 0) && (errno != EEXIST))
{
perror("mkfifo");
unlink(FIFO2);
exit(EXIT_FAILURE);
}
printf("打開有名管道1來讀:\n");
readfd = open(FIFO1,O_RDONLY,0); //此處阻塞,直到管道另外一端打開管道的寫端
printf("打開有名管道2來寫:\n");
writefd = open(FIFO2,O_WRONLY,0);
printf("服務器端,將兩個有名管道都打開:\n");
server(readfd,writefd);
exit(0);
}
void server(int readfd,int writefd)
{
int fd;
ssize_t n;
char buf[MAXLINE];
//從管道中讀出資料(檔案路徑名)
printf("服務器端,從FIFO讀檔案路徑:\n");
if((n = read(readfd,buf,MAXLINE)) == 0) //此處阻塞,直到管道1中有資料可以讀出
{
perror("read");
exit(EXIT_FAILURE);
}
buf[n] = '\0';
printf("服務器端,從有名管道1中讀出的檔案路徑大小為:%d,路徑為:%s\n",n,buf);
printf("服務器端,將檔案打開后讀出寫入到有名管道2中:\n");
if((fd = open(buf,O_RDONLY)) < 0)
{
//錯誤必須告訴客戶端
printf("服務器端寫入錯誤資訊到有名管道2中:\n");
snprintf(buf+n,sizeof(buf)-n,":can't open,%s\n",strerror(errno));
n = strlen(buf);
write(writefd,buf,n);
}
else
{
printf("服務器端寫入檔案內容到有名管道2中:\n");
while((n = read(fd,buf,MAXLINE)) > 0)
write(writefd,buf,n);
close(fd);
}
}
客戶端原始碼如下:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<fcntl.h>
#include"fifo.h"
void client(int,int);
int main(int argc,char** argv)
{
int readfd,writefd;
printf("打開有名管道1來寫:\n");
writefd = open(FIFO1,O_WRONLY,0);
printf("打開有名管道2來讀:\n");
readfd = open(FIFO2,O_RDONLY,0);
printf("客戶端,將兩個有名管道都打開:\n");
client(readfd,writefd);
close(readfd);
close(writefd);
unlink(FIFO1);
unlink(FIFO2);
exit(0);
}
void client(int readfd,int writefd)
{
size_t len;
ssize_t n;
char buf[MAXLINE];
fgets(buf,MAXLINE,stdin); //從標準輸入讀入檔案路徑名
len = strlen(buf);
if(buf[len-1] == '\n') //洗掉換行符
len--;
printf("從標準輸入讀入檔案路徑,寫入有名管道:\n");
n = write(writefd,buf,len); //利用管道2的寫端將資料寫入管道
printf("客戶端從標準輸入讀入檔案路徑寫入到有名管道中的大小為:%d,路徑為:%s\n",n,buf);
//從管道中讀出資料,寫到標準輸出
printf("從有名管道2中讀出資料,寫入標準輸出(錯誤輸出):\n");
while((n = read(readfd,buf,MAXLINE)) > 0) //利用管道1的讀端將資料讀出到標準輸出
write(STDOUT_FILENO,buf,n);
}
先執行服務器端后,服務器端為什么就直接退出了,沒有阻塞在open函式呢??客戶端都沒運行
最后的運行結果為:
[tsj@tangshaojie 管道和FIFO 11:03]$gcc -o FIFO_server2 FIFO_server2.c
FIFO_server2.c: In function ‘server’:
FIFO_server2.c:58:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 4 has type ‘int’ [-Wformat=]
snprintf(buf+n,sizeof(buf)-n,":can't open,%s\n",strerror(errno));
^
FIFO_server2.c:58:3: warning: format ‘%s’ expects argument of type ‘char *’, but argument 4 has type ‘int’ [-Wformat=]
FIFO_server2.c:59:7: warning: incompatible implicit declaration of built-in function ‘strlen’ [enabled by default]
n = strlen(buf);
^
[tsj@tangshaojie 管道和FIFO 11:03]$./FIFO_server2
打開有名管道1來讀:
打開有名管道2來寫:
服務器端,將兩個有名管道都打開:
服務器端,從FIFO讀檔案路徑:
服務器端,從有名管道1中讀出的檔案路徑大小為:-1,路徑為:
服務器端,將檔案打開后讀出寫入到有名管道2中:
服務器端寫入錯誤資訊到有名管道2中:
[tsj@tangshaojie 管道和FIFO 11:04]$
我找了好長時間,是在不知道原因在哪里?求大神幫忙解答一下,不甚感激!!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/153598.html
標籤:網絡通信
