linux Dup2 网络转发,Linux系统编程:dup2()重定向
对于Dup2 的理解:
源代码:
1 #include
2 #include
3 #include
4 #include
5 #include
6
7 #define MSGSIZE 20
8 #define READ 0
9 #define WRITE 1
10
11 int main(int argc, char const *argv[])12 {13 int p[2], bytes, res, c;14 char inbuf[10240];15 intpid;16 printf("%c", 11);17 if(pipe(p) == -1){//creat the pipe , if pipe is built failed , exit .
18 perror("pip call");19 exit(1);20 }21 pid =fork();22 if(pid != 0){//creat parent pid and child pid.
23 close(p[READ]);//close parent pipe read
24 dup2(p[WRITE], 1);25 close(p[WRITE]);//close parent pipe write
26 execlp(argv[1], argv[1], NULL);27 }28 else{29
30 close(p[WRITE]);//close child pipe write
31
32 dup2(p[READ],0);33
34 close(p[READ]);//close child pipe read
35
36 execlp(argv[2], argv[2], NULL);37 }38 return 0;39 }
通过命令行输出:
./a.out “ls” “ps”
仅仅在终端执行了ps的命令, 而没有看到ls 命令的结果。
因此,开始走入了第一个误区:父进程没有执行
通过调试 在父进程执行if条件中加入以下代码:
if(pid != 0){
printf("4556\n");
close(p[READ]);
dup2(p[WRITE], 1);
close(p[WRITE]);
printf("4556\n");
execlp(argv[1], argv[1], NULL);
}
加入了2个printf , 但是只有dup2 上面的printf 结果输出到屏幕上,因此我注释了 dup2(p[WRITE], 1); 结果在父进程if语句中的dup2 后面的命令都执行并且输出到屏幕上了。通过查找dup2 命令发现了重定向的强大之处。
先解释下dup2 命令,
int dup2(int filedes, int filedes2);
说明:
用dup2 则可以用filedes2 参数指定新描述符的数值。如果filedes2 已经打开,则先将其关闭。如若filedes 等于filedes2,则返回filedes2,而不关闭它。
dup2(p[WRITE], 1); 这句话可以理解为将标准输出重定向到p[WRITE], 因此在这句话后面的所有printf 语句打印或者exec 执行的内容都输入到了p[WRITE]中。刚开始有个迷惑,就是既然已经close(1)了,为什么还能输入到p[WRITE]中,通过自己的直觉判断,应当是close(1)关闭了屏幕的输出,但是它有缓冲区保存printf打印出的内容,并且由于重定向的关系,输进了p[WRITE]中。
代码:
1 #include
2 #include
3 #include
4 #include
5 #include
6
7 #define MSGSIZE 20
8 #define READ 0
9 #define WRITE 1
10
11 int main(int argc, char const *argv[])12 {13 int p[2], bytes, res, c;14 char inbuf[10240];15 intpid;16 printf("%c", 11);17 if(pipe(p) == -1){//creat the pipe , if pipe is built failed , exit .
18 perror("pip call");19 exit(1);20 }21 pid =fork();22 if(pid != 0){//creat parent pid and child pid.
23 close(p[READ]);//close parent pipe read
24 dup2(p[WRITE], 1);25 close(p[WRITE]);//close parent pipe write
26 printf("123!\n");27 execlp(argv[1], argv[1], NULL);28 perror("execlp");//error output
29 }30 else{31 while(1){32 res = read(p[READ], inbuf, 10240);33 if(res>0)34 printf("%s\n", inbuf);35 break;36 }37
38 close(p[WRITE]);//close child pipe write
39
40 dup2(p[READ],0);41
42 close(p[READ]);//close child pipe read
43
44 execlp(argv[2], argv[2], NULL);45 }46 return 0;47 }
通过在子进程中用while(1)循环读取p[READ]内容,发现读出了父进程本应在屏幕上打印的内容,因此父进程是执行了所有命令行,只是通过重定向命令存到了p[WRITE]管道中。
由于有dup2(p[READ], 0) 命令,因此猜测标准输入的文件描述符定向到了p[READ] , 因此如果猜测没错,通过getchar()读取文件标准输入并把P[READ]的内容输出到屏幕上则证明我猜想没错。
代码:
1 #include
2 #include
3 #include
4 #include
5 #include
6
7 #define MSGSIZE 20
8 #define READ 0
9 #define WRITE 1
10
11 int main(int argc, char const *argv[])12 {13 int p[2], bytes, res, c;14 char inbuf[10240];15 intpid;16 printf("%c", 11);17 if(pipe(p) == -1){//creat the pipe , if pipe is built failed , exit .
18 perror("pip call");19 exit(1);20 }21 pid =fork();22 if(pid != 0){//creat parent pid and child pid.
23 close(p[READ]);//close parent pipe read
24 dup2(p[WRITE], 1);25 close(p[WRITE]);//close parent pipe write
26 printf("123!\n");27 execlp(argv[1], argv[1], NULL);28 perror("execlp");//error output
29 }30 else{31 //while(1){32 //res = read(p[READ], inbuf, 10240);33 //if(res>0)34 //printf("%s\n", inbuf);35 //break;36 //}
37
38 close(p[WRITE]);//close child pipe write
39
40 dup2(p[READ],0);41 while((c=getchar()) != -1){42 printf("%c", c);43 }44 close(p[READ]);//close child pipe read
45
46 execlp(argv[2], argv[2], NULL);47 }48 return 0;49 }
通过在dup2(p[READ], 0) 后面while循环读入输入流输入的字符并且打印出来, 发现结果果然是p[READ]的内容,猜疑没错。
为了更清楚的理解dup2的重定向含义,想理解dup2(fd,0)和dup2(0,fd)功能相同吗?
为了得到答案,找些资料发现,答案是不同。
测试代码:
1 #include
2 #include
3 #include
4
5 #define BUFMAXSIZE 4096
6
7 int main(int argc, char *argv[])8 {9 intfd;10 intn;11 charbuf[BUFMAXSIZE];12 intfs;13 fs = open("test", O_RDWR);14 if((fd = open("duan", O_RDWR )) == -1)15 {16 perror("open error!");17 return(1);18 }19
20 dup2(fd, 1); //dup2(0,fd);
21
22 while((n = read(fs, buf, BUFMAXSIZE)) > 0)23 {24 printf("begin to read...\n");25 if(write(STDOUT_FILENO, buf, n) !=n)26 {27 perror("write error!");28 return(1);29 }30 printf("end to write...\n");31 }32 if(n < 0)33 {34 perror("read error");35 return(1);36 }37
38 return 0;39 }
dup(fd, 0) 这段代码测试, 打印出了duan 文件里面的内容。
之后创建个文件Levi 里面写和duan 文件不同的内容。
通过./a. out < Levi输出:
第一个输出是dup(fd, 0) 输出了Duan 文件的内容。即是fd的内容
第二个输出是dup(0, fd) 输出了Levi 文件的内容。即是 通过文件重定向到标准输入的内容。
从图中的输出结果已经可以看到两者的区别了。
第一种dup2(fd,0)之前已经将fd 初始化指向到文本Duan了,
并且不会被后面的代码所修改。
第二种dup2(0,fd)则将fd 重新指向到文件描述符0所代表的文件(即终端标准输入)了。
那么可以看到,程序的执行中不会再读取Duan 文件了。
而是进入了一种交互模式。
另外,这时“输入重定向”也可以生效了。
文件描述符0被 “
所以,这里直接输出了该文本的内容。
dup2(fd,0) 相当于“输入重定向”的功能,
dup2(0,fd) 不是表示fd 所指的文件接收来自终端的输入,因为,fd 已经不再指向原来的那个文件了。
它和文件描述符0 已经在共享同一个文件表项(即指向终端标准输入的那个表项)了。
“输出重定向”的功能可以用dup2(fd ,1) 替代。
dup2(fd,1) 和dup2(1,fd) 也是大同小异。
linux Dup2 网络转发,Linux系统编程:dup2()重定向相关推荐
- Linux shell、内核及系统编程精品资料下载汇总 topsage
shell编程.sed.awk.grep相关: UNIX shell by Example 第四版 UNIX shell范例精解 (第4版) 中文高清PDF下载 Shell脚本学习指南(Classic ...
- 【Linux】网络篇二--TCP编程
网络篇二--TCP编程 一.TCP编程实现 1.编程步骤 2.socket函数 3.bind函数 4.地址转换函数 5.listen函数 6.accept函数 7.connect函数 8.send函数 ...
- linux内核网络协议栈--linux bridge(十九)
1 . 前言 本文是参考附录上的资料整理而成,以帮助读者更好的理解kernel中brdige 模块代码. 2. 网桥的原理 2.1 桥接的概念 简单来说,桥接就是把一台机器上的若干个网络接口" ...
- linux内核网络初始化,Linux内核--网络栈实现分析
本文分析基于内核Linux Kernel 1.2.13 以后的系列博文将深入分析Linux内核的网络栈实现原理,这里看到曹桂平博士的分析后,也决定选择Linux内核1.2.13版本进行分析. 原因如下 ...
- linux 挂载网络文件系统,linux 挂载网络文件系统
网络文件系统介绍 linux NFS 配置步骤 linux NFS 配置步骤 NFS server可以看作是一个FILE SERVER,它可以让你的PC通过网络将远端得NFS SERVER共享出来的档 ...
- linux内核网络协议栈--linux网络设备理解(十三)
网络层次 linux网络设备驱动与字符设备和块设备有很大的不同. 字符设备和块设备对应/dev下的一个设备文件.而网络设备不存在这样的设备文件.网络设备使用套接字socket访问,虽然也使用read, ...
- 浅析linux内核网络协议栈--linux bridge
1 . 前言 本文是参考附录上的资料整理而成,以帮助读者更好的理解kernel中brdige 模块代码. 2. 网桥的原理 2.1 桥接的概念 简单来说,桥接就是把一台机器上的若干个网络接口" ...
- linux内核网络基础,linux网络内核基础.doc
linux网络内核基础 linux内核网络栈代码的准备知识 1. linux内核ipv4网络部分分层结构:BSD socket层: 这一部分处理BSD socket相关操作,每个socket在内核中以 ...
- 【Linux】网络套接字编程
前言 在掌握一定的网络基础,我们便可以先从代码入手,利用UDP协议/TCP协议进行编写套接字程序,明白网络中服务器端与客户端之间如何进行连接并且通信的. 目录 一.了解源目的IP.端口.网络字节序.套 ...
最新文章
- C宏定义中## 和# 的含义
- BaiDu校招2016计算机视觉笔试试题
- Web系统开发构架再思考-前后端的完全分离
- fmax()函数以及C ++中的示例
- 1.5编程基础之循环控制 37 雇佣兵
- mysql抖动可能的原因_MySQL应对网络抖动问题
- 关于Qt5.10调试时出现“qtcreatorcdbext.dll cannot be found.”的解决方案
- 将WebAPI发布到本地服务器与远程服务器
- luogu1984 烧水问题 (找规律)
- Stroustrup 谈 C++ 11的新特性
- 计算机组成原理——输入输出系统
- P3376 【模板】网络最大流
- 何谓服务器(Server) ?
- 胃酸过多症的食疗方 [转]
- 周志华 《机器学习初步》 绪论
- 网红为什么能增加ROI?什么样的网红才能增加ROI
- ELK学习笔记之F5 DNS可视化让DNS运维更安全更高效-F5 ELK可视化方案系列(3)
- 熬夜整理小米Java面试题,已拿offer
- 辨析 总结PMP各种BS结构
- 苹果手机免密支付怎么取消_苹果取消配件,废旧手机配件真的没用了?
热门文章
- 软件测试上线标准是什么?我来告诉你
- linux find -size参数,Linux中find的用法
- 【面试题系列】混合夺命21问,你能扛到第几问?
- WIN 10系统启动程序出现 MSVCR110.dll和MSVCP110.dll问题解决方法
- Brew----常见问题 ( 最近一次更新 2011--04--30)
- 白帽子社区端午节活动-白帽寻宝记-纪念屈原Writeup
- PlantUML常用命令笔记
- Revit 学习资源
- 部分关于需求分析和软件构架的书籍
- 计算机专业英语2008影印版第四章翻译,计算机专业英语2008影印版 翻译