管道学习有一段时间了, 感觉自己应该把这段时间的学习点滴记录下来, 下面就结合几道编程题将所学知识串接一下:
题目1:通过管道进行的父/子进程通信
涉及主要知识点:未命名管道
/*
**熟悉:
** (1)read, write, fork 以及一些进程的东西
**该程序主要练习具有亲缘关系间进程的通信过程, 即无名管道, 通过该练习, 可知管道通信的步骤:
** (1)创建管道.
** (2)创建子进程.
** (3)关闭不必要的读写端.
** (4)按照需要进行读写数据.
** (5)退出.
*/
#include
#include
#define MAXLINE 255
int main()
{
int pipe1[2];
int n;
char line[MAXLINE];
pid_t pid;
if(pipe(pipe1) < 0){
printf("创建管道失败!\n");
return -1;
}
if((pid = fork()) < 0) {
printf("创建子进程失败\n");
return -1;
}else if(pid > 0) {
close(pipe1[0]);
write(pipe1[1], "你好! 我是父进程!\n", 50);
}else{
// sleep(1);
close(pipe1[1]);
n = read(pipe1[0], line, MAXLINE);
write(NULL, line, n); //写至标准输出
}
// printf("\n");
return 0;
}
题目:使用两个个管道进程全双工通信:父进程从管道接收数据,然后将数据显示,再给子进程发送一个数据;子进程从管道接收数据,然后将数据显示,再给父进程发送一个数据。
/*
**该程序主要练习利用无名管道实现全双工通信, 不关闭相应端
*/
#include
#include
#include
#define MAXLINE 50
int main()
{
int pipe1[2], n;
char line[MAXLINE];
pid_t pid;
if(pipe(pipe1) < 0){
printf("创建管道失败!\n");
return -1;
}
if((pid = fork()) <0){
printf("创建子进程失败!\n");
return -1;
} else if(pid == 0) {
n = read(pipe1[0], line, MAXLINE);
printf("子进程读到的数据: %s\n", line);
sleep(1);
write(pipe1[1], "你好! 我是子进程!", 50 );
exit(0);
}else{
write(pipe1[1], "你好!我是父进程!", 50);
//sleep(1);
n = read(pipe1[0], line, MAXLINE);
printf("父进程读到的数据:%s\n", line);
exit(0);
}
return 0;
}
通过管道模拟shell命令:cat file | sort
涉及主要知识点:未命名管道、重定向
/*
** popen 在调用进程与管道之间建立一条管道,
**返回一个FILE的指针, 该指针或者用于输入或者用于输出
*/
#include
#include
#include
#include
#include
#define MAXLINE 50
int main()
{
int n, len;
char line[MAXLINE], command[MAXLINE], command1[MAXLINE];
FILE *fp, *fp1;
fgets(line, MAXLINE, stdin);
len = strlen(line);
if(line[len-1] == '\n'){
len--;
}
snprintf(command, sizeof(command), "cat %s", line);
fp = popen(command, "r");
snprintf(command1, sizeof(command1), "sort %s", line);
fp1 = popen(command1, "r");
printf("sort前的数据是:\n");
while(fgets(line, MAXLINE, fp) != NULL) {
// snprintf(command1, sizeof(command1), "sort %s", line);
// fp1 = popen(command1, "r");
fputs(line, stdout);
}
printf("sort后的数据是:\n");
while(fgets(line, MAXLINE, fp1) != NULL) {
fputs(line, stdout);
}
pclose(fp);
pclose(fp1);
exit(0);
}
题目3:命名管道(FIFO)实现客户-服务器关系。
/*
** 了解客户-服务器模型通信的思想, 掌握snprintf的用法
*/
#include
#include
#include
#include
#include
#include
#define MAXLINE 50
void client(int rd, int wd)
{
int n;
int len;
char line[MAXLINE];
printf("请输入:\n");
fgets(line, MAXLINE, stdin);
len = strlen(line);
if(line[len-1] == '\n'){
len--;
}
printf("line的内容是: %s\n", line);
write(wd, line, len);
printf("已写入!\n");
// sleep(2);
while((n = read(rd, line, MAXLINE)) > 0){
write(STDOUT_FILENO, line, n);
}
printf("客户端结束\n");
}
void server(int rd, int wd)
{
int n;
int len;
int fd;
char line[MAXLINE];
if((n = read(rd, line, MAXLINE)) < 0) {
printf("服务器读管道出错!\n");
exit(0);
}
printf("开始打开:\n");
printf("%s\n", line);
if((fd = open(line, O_RDONLY)) < 0) {
snprintf(line+n, sizeof(line)-n , ":can not open, %s\n", strerror(errno));
printf("服务器打开文件错误!\n");
n = strlen(line);
write(wd, line, n);
} else {
while((n = read(fd, line, MAXLINE)) > 0) {
write(wd, line, n);
}
close(fd);
}
}
int main()
{
int pipe1[2], pipe2[2];
pid_t pid;
int fd;
if(pipe(pipe1) < 0) {
printf("创建管道1失败!\n");
return -1;
}
if(pipe(pipe2) < 0) {
printf("创建管道2失败!\n");
return -1;
}
if((pid = fork()) < 0) {
printf("创建子进程失败!\n");
return -1;
}else if(pid > 0) {
close(pipe1[0]);
close(pipe2[1]);
client(pipe2[0], pipe1[1]);
exit(0);
} else {
sleep(2);
close(pipe1[1]);
close(pipe2[0]);
server(pipe1[0], pipe2[1]);
waitpid(pid , NULL, 0);
exit(0);
}
printf("\n");
return 0;
}
阅读(1111) | 评论(0) | 转发(0) |