UNIX:在父子进程间用管道技术通信
2013-01-16 11:28
274 查看
《Unix网络编程》这本书附带了许多短小精美的小程序,我在阅读此书的时候,将书上的代码按照自己的理解重写了一遍(大部分是抄书上的),加深一下自己的理解(纯看书太困了,呵呵)。此例子在Ubuntu10.04上测试通过。
PS:程序里使用了包裹函数(首字母是大写的函数)和常量(所有字母都是大写的常量)的声明在my_unp.h文件中,定义在unp_base.c和unp_thread.c中,地址:http://blog.csdn.net/aaa20090987/article/details/8096701
程序简介:这个程序演示了父子进程之间如果利用管道技术进行通信。
上代码:
[cpp] view
plaincopyprint?
#include "my_unp.h"
void client(int readfd, int writefd)
{
size_t len;
ssize_t n;
char buff[MAXLINE];
//从终端读入一行数据(文件路径)
Fgets(buff, MAXLINE, stdin);
len = strlen(buff);
if( '\n' == buff[len-1] )
len--;
//将其写入管道
Write(writefd, buff, len);
//然后从管道中读出数据
while( (n=Read(readfd, buff, MAXLINE)) > 0 )
Write(STDOUT_FILENO, buff, n);
}
void server(int readfd, int writefd)
{
int fd;
ssize_t n;
char buff[MAXLINE];
//从管道中读出一行数据(文件路经)
if( (n=Read(readfd, buff, MAXLINE)) == 0 )
error_quit("end of file while reading pathname");
buff
= '\0';
//打开文件
fd = open(buff, O_RDONLY);
//如果打开失败,就将失败原因写入管道
if( fd < 0 )
{
snprintf(buff+n, sizeof(buff)-n, ": can't open, %s\n",
strerror(errno));
n = strlen(buff);
Write(writefd, buff, n);
}
//否则,将文件内容写入管道
else
{
while( (n=Read(fd, buff, MAXLINE)) > 0 )
Write(writefd, buff, n);
Close(fd);
}
}
int main(int argc, char **argv)
{
int pipe1[2], pipe2[2];
pid_t childpid;
Pipe(pipe1);
pipe(pipe2);
childpid = Fork();
//父子进程分别关闭自己不需要的管道端口
if( childpid == 0 )
{
Close(pipe1[1]);
Close(pipe2[0]);
server(pipe1[0], pipe2[1]);
}
else
{
Close(pipe1[0]);
Close(pipe2[1]);
client(pipe2[0], pipe1[1]);
//父进程必须等子进程退出之后才能退出
Waitpid(childpid, NULL, 0);
}
return 0;
}
运行示例(红色字体的为输入)
qch@ubuntu:~/code$gcc my_unp.c temp.c -o temp
#打开一个有两行字符串的文本文件
qch@ubuntu:~/code$./temp
text.txt
I'amChinese.
Hello,world.
#打开一个我们不能读的文件
qch@ubuntu:~/code$./temp
/etc/shadow
/etc/shadow:can't open, Permission denied
#打开一个不存在的文件
qch@ubuntu:~/code$ ./temp
aaaaa
aaaaa:can't open, No such file or directory
PS:程序里使用了包裹函数(首字母是大写的函数)和常量(所有字母都是大写的常量)的声明在my_unp.h文件中,定义在unp_base.c和unp_thread.c中,地址:http://blog.csdn.net/aaa20090987/article/details/8096701
程序简介:这个程序演示了父子进程之间如果利用管道技术进行通信。
上代码:
[cpp] view
plaincopyprint?
#include "my_unp.h"
void client(int readfd, int writefd)
{
size_t len;
ssize_t n;
char buff[MAXLINE];
//从终端读入一行数据(文件路径)
Fgets(buff, MAXLINE, stdin);
len = strlen(buff);
if( '\n' == buff[len-1] )
len--;
//将其写入管道
Write(writefd, buff, len);
//然后从管道中读出数据
while( (n=Read(readfd, buff, MAXLINE)) > 0 )
Write(STDOUT_FILENO, buff, n);
}
void server(int readfd, int writefd)
{
int fd;
ssize_t n;
char buff[MAXLINE];
//从管道中读出一行数据(文件路经)
if( (n=Read(readfd, buff, MAXLINE)) == 0 )
error_quit("end of file while reading pathname");
buff
= '\0';
//打开文件
fd = open(buff, O_RDONLY);
//如果打开失败,就将失败原因写入管道
if( fd < 0 )
{
snprintf(buff+n, sizeof(buff)-n, ": can't open, %s\n",
strerror(errno));
n = strlen(buff);
Write(writefd, buff, n);
}
//否则,将文件内容写入管道
else
{
while( (n=Read(fd, buff, MAXLINE)) > 0 )
Write(writefd, buff, n);
Close(fd);
}
}
int main(int argc, char **argv)
{
int pipe1[2], pipe2[2];
pid_t childpid;
Pipe(pipe1);
pipe(pipe2);
childpid = Fork();
//父子进程分别关闭自己不需要的管道端口
if( childpid == 0 )
{
Close(pipe1[1]);
Close(pipe2[0]);
server(pipe1[0], pipe2[1]);
}
else
{
Close(pipe1[0]);
Close(pipe2[1]);
client(pipe2[0], pipe1[1]);
//父进程必须等子进程退出之后才能退出
Waitpid(childpid, NULL, 0);
}
return 0;
}
运行示例(红色字体的为输入)
qch@ubuntu:~/code$gcc my_unp.c temp.c -o temp
#打开一个有两行字符串的文本文件
qch@ubuntu:~/code$./temp
text.txt
I'amChinese.
Hello,world.
#打开一个我们不能读的文件
qch@ubuntu:~/code$./temp
/etc/shadow
/etc/shadow:can't open, Permission denied
#打开一个不存在的文件
qch@ubuntu:~/code$ ./temp
aaaaa
aaaaa:can't open, No such file or directory
相关文章推荐
- unix学习笔记---------自己写的管道实例----父子进程通信
- UNIX环境高级编程学习之第十五章进程间通信 - 通过半双工匿名管道实现父子进程通信
- UNIX环境高级编程学习之第十五章进程间通信 - 通过匿名管道实现父子进程同步
- 应用管道实现父子进程之间的通信
- 匿名管道实现父子进程之间的通信....
- linux进程通信之使用匿名管道进行父子进程通信
- 父子进程间的单向管道通信
- 匿名管道实现父子进程之间的通信....
- 匿名管道实现父子进程之间的通信....
- 多进程(父子进程)中的管道通信
- 进程通信之二 管道技术第二篇 匿名管道
- [Linux管道和IPC]使用信号量和共享内存进行父子进程通信
- 简单的实现,在无名管道里父子进程间的通信(大小写的转换)
- Linux下父子进程匿名管道通信
- 进程通信之二 管道技术第二篇 匿名管道
- Linux父子进程通信--管道及FIFO通信
- fork()+pipe() --> 父子进程间通过管道通信
- 进程通信之二 管道技术第一篇 输入输出的重定向
- 【C语言】【unix c】如何使用管道实现两个进程间的通信
- 进程通信之二 管道技术第一篇 输入输出的重定向