两个进程之间通过管道通信。父进程(表现为client函数)接受用户输入一个文件名,然后通过管道传递给子进程(在server函数内),子进程打开这个文件,成功后,将这个文件的内容读出,并通过管道将读取的内容传递给父进程,父进程读取管道的内容,并显示在屏幕上
现在有源程序Pipe.cpp,编译链接后得到可执行文件Pipe,在Linux下面执行:
$./Pipe
Pipe.cpp
这时结果出错,无法显示Pipe.cpp文件的内容,按照源程序的意思应该是可以显示Pipe.cpp文件的内容的
源程序如下
//Pipe.cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXLINE = 128;
void client(int readfd, int writefd)
{
size_t len;
size_t n;
char buff[MAXLINE];
fgets(buff, MAXLINE, stdin); //读取一个文件名
len = strlen( buff );
if ( buff[len - 1] == '\n' ) //如果最后一个字符为回车
{
len--;
}
if (write(writefd, buff, len) == -1 ) //将文件名写入管道
{
cerr << "client write error" << endl;
exit(0);
}
else
{
cout << "client write pathname successfully!" << endl;
}
while ( (n = read(readfd, buff, MAXLINE)) > 0) //读取管道内容
{
buff[n] = '\0'; //加上结束标志
cout << buff << endl;
}
}
void server(int readfd, int writefd)
{
int fd;
ssize_t n;
char buff[MAXLINE + 1];
if ( (n = read(readfd, buff, MAXLINE) ) == 0 )//从管道内读取一个文件名
{
cerr << "end-of-file while reading pathename" << endl;
}
else if ( n == -1)
{
cerr << "server read error" << endl;
}
buff[n] = '\0';
if ( (fd = open(buff, O_RDONLY) ) < 0 ) //打开这个文件
{
cerr << "open(buff, O_RDONLY) error" << endl;
snprintf( buff + n, sizeof(buff) - n, " :can't open, %s\n", strerror(errno));
n = strlen(buff);
write( writefd, buff, n);
}
else
{
cout << "open " << buff << " successfully!" << endl;
while( (n = read(fd, buff, MAXLINE) > 0 ) ) //读取文件里的内容
{
if ( write(writefd, buff, n) == -1) //将读取的内容写入管道
{
cerr << "server write(writefd, buff, n) error" << endl;
exit(0);
}
//余下的程序
else
{
cout << "server write successfully!" << endl;
}
}
close(fd);
}
}
int main(int argc,char **argv)
{
int pipe1[2], pipe2[2];
pid_t childpid;
pipe(pipe1); //创建管道
pipe(pipe2);
if( (childpid = fork() ) == 0)
{
close(pipe1[1]); //子进程中,管道为读
close(pipe2[0]); //管道为写
server(pipe1[0], pipe2[1]);
exit(0);
}
close(pipe1[0]); //父进程,管道为写
close(pipe2[1]); //管道为读
client(pipe2[0], pipe1[1]);
waitpid( childpid, NULL, 0);
return 0;
}