【Linux】管道的通信总结
来源:互联网 发布:java面试宝典2015版 编辑:程序博客网 时间:2024/06/01 19:05
一、popen
管道常见的操作是创建一个管道连接到另一个进程,然后读其输出或向其输入端发送数据
标准I/O库提供了函数popen, 该函数是:创建一个管道,调用fork产生一个子进程,关闭管道的不使用端,
执行一个shell以运行命令,然后等待命令终止。
#include <stdio.h>
FILE *popen(const char *command, const char *type);
返回:若成功则为文件指针,若出错则为NULL
如果type为r, 那么调用进程读进command的标准输出
如果type为w, 那么调用进程写到command的标准输入
测试代码:
#include <stdio.h>#include <string.h>int main(void){FILE *fp = NULL;char buff[1024] = {0};char command[1024] = {0};memset(command, 0x00, sizeof(command));snprintf(command, sizeof(command), "%s", "ls");fp = popen(command, "r");memset(buff, 0x00, sizeof(buff));while(fgets(buff, sizeof(buff), fp) != NULL){printf("buff[%s]\n", buff);memset(buff, 0x00, sizeof(buff));}fclose(fp);return 0;}
二、 pipe
int pipe(int fd[2]);返回两个文件描述符,fd[0]和fd[1], 前者打开来读,后者打开来写成功返回0, 出错返回-1
测试代码:
#include <stdio.h>#include <string.h>#include <unistd.h>int main(void){char writebuff[1024] = {0};char readbuff[1024] = {0};char readbuff2[1024] = {0};int pipe_in[2], pipe_out[2];pid_t pid;printf("start test_pipe\n");pipe(&pipe_in);// 创建父进程中用于读取数据的管道pipe(&pipe_out);// 创建父进程中用于写入数据的管道if ( (pid = fork()) == 0) {// 子进程 close(pipe_in[0]);// 关闭父进程的读管道的子进程读端 close(pipe_out[1]);// 关闭父进程的写管道的子进程写端 dup2(pipe_in[1], STDOUT_FILENO);// 复制父进程的读管道到子进程的标准输出 dup2(pipe_out[0], STDIN_FILENO);// 复制父进程的写管道到子进程的标准输入 close(pipe_in[1]);// 关闭已复制的读管道 close(pipe_out[0]);// 关闭已复制的写管道 // 从标准输入读取数据 read(STDIN_FILENO, readbuff2, sizeof(readbuff2)); // 使用exec执行命令 execl("/bin/sh", "sh", "-c", readbuff2, NULL);} else {// 父进程 close(pipe_in[1]);// 关闭读管道的写端 close(pipe_out[0]);// 关闭写管道的读端 // 向pipe_out[1]中写数据 snprintf(writebuff, sizeof(writebuff), "%s", "ls"); write(pipe_out[1],writebuff,strlen(writebuff));// 这里sleep 3秒,为了是确认子进程先执行完成 sleep(3); // 从pipe_in[0]中读结果 read(pipe_in[0], readbuff, sizeof(readbuff)); printf("readbuff[%s]\n", readbuff); close(pipe_out[1]);// 关闭写管道 close(pipe_in[0]);// 关闭读管道 // 使用wait系列函数等待子进程退出并取得退出代码 waitpid(pid, NULL,0);}return 0;}
三、socketpair
#include <sys/socket.h>int socketpair(int family, int type, int protocol, int socketfd[2]);返回0成功,返回-1出错family必须是AF_LOCAL或者AF_UNIX, type可以是SOCK_STREAM或者SOCK_DGRAM, protocol必须是0创建的两个套接字描述符sockefd[0]和sockefd[1]都是可读写
测试代码:
#include <stdio.h>#include <string.h>#include <sys/types.h> /* See NOTES */#include <sys/socket.h>#include <unistd.h>int main(void){char writebuff[1024] = {0};char readbuff[1024] = {0};int fd[2];pid_t pid;socketpair(AF_UNIX, SOCK_STREAM, 0, fd) ;// 创建管道if ( (pid = fork()) == 0) {// 子进程close(fd[0]);// 关闭管道的父进程端dup2(fd[1], STDOUT_FILENO);// 复制管道的子进程端到标准输出dup2(fd[1], STDIN_FILENO);// 复制管道的子进程端到标准输入close(fd[1]);// 关闭已复制的读管道// 使用exec执行命令execl("/bin/sh", "sh", "-c", "sort", NULL);} else {// 父进程close(fd[1]);// 关闭管道的子进程端// 往fd[0]中写数据snprintf(writebuff, sizeof(writebuff), "%s", "j am king\n");write(fd[0],writebuff,strlen(writebuff));memset(writebuff, 0x00, sizeof(writebuff));snprintf(writebuff, sizeof(writebuff), "%s", "i am queue\n ");write(fd[0],writebuff,strlen(writebuff)); // 通知对端数据发送完毕shutdown(fd[0], SHUT_WR);// 从fd[0]中读数据read(fd[0], readbuff, sizeof(readbuff));printf(" readbuff[%s]\n", readbuff);/* 读取剩余数据 */close(fd[0]);// 关闭管道// 使用wait系列函数等待子进程退出并取得退出代码 waitpid(pid, NULL,0);}}
0 0
- 【Linux】管道的通信总结
- Linux进程的管道通信
- linux的进程通信-管道
- Linux下的管道通信
- Linux下的管道通信
- Linux进程通信总结(二) --管道
- linux进程间通信-----管道总结实例
- Linux进程间的通信--管道通信
- Linux系统管道和有名管道的通信机制
- 转载:管道通信总结
- linux下的管道通信程序
- linux下的管道通信程序
- 一个LINUX下管道通信的例子
- linux进程间的通信-无名管道
- Linux的进程间通信 - 管道
- Linux的进程间通信 - 管道
- [Linux]进程之间的管道通信
- linux的通信方式之匿名管道
- 个人学习安卓基础的小逻辑-勾选和滑动控件
- 软件光栅器六之透视纹理映射
- Android Canvas drawArc方法介绍
- 职责链模式
- 搜索专题(BFS)HDU 1253-胜利大逃亡
- 【Linux】管道的通信总结
- Java模拟post请求
- gradle bug solution
- 滚动条
- TimePicker DatePicker使用
- VS2013/MFC编程入门之二十二(常用控件:按钮控件的编程实例)
- 从上往下遍历二元树
- 在Java中使用标准输入输出设备进行字符串,整数浮点数等 的输入输出操作
- 【计算机视觉】OpenCV的最近邻开源库FLANN