创建一条无名管道并且给你两个文件描述符(读写的文件描述符)
pipefd[0]:读端
pipefd[1]:写端
思路:
只需要一个.c即可,fork一次即可(因为用的是无名管道)
注意:
父进程:
发:scanf + write //你好我是旦丁
收:read + printf //卡住
子进程:
发:scanf《卡》 + write “我不是旦丁”
收:read《卡》 + printf
#include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <sys/wait.h> #include <sys/types.h> #include <unistd.h> int main() { //创建两个无名管道 int pipefd1[2] = {0}; int pipefd2[2] = {0}; int pipe_father = pipe(pipefd1); int pipe_son = pipe(pipefd2); pid_t ret = fork(); //创建进程 if (ret == -1) { perror("fork"); } else if (ret == 0) //子进程 { char msg_son[32] = {0}; char msg_father[32] = {0}; while (1) { memset(msg_father, 0, 32); read(pipefd2[0], msg_father, 32); //读阻塞,当管道没有数据时,对管道进行读取会阻塞 printf("父亲说:%s\n", msg_father); printf("儿子:"); scanf("%s", msg_son); write(pipefd1[1], msg_son, strlen(msg_son)); } close(pipefd1[1]); close(pipefd2[0]); } else //父进程 { char msg_father[32] = {0}; char msg_son[32] = {0}; while (1) { printf("父亲:"); scanf("%s", msg_father); write(pipefd2[1], msg_father, strlen(msg_father)); memset(msg_son, 0, 32); read(pipefd1[0], msg_son, 32); printf("儿子说:%s\n", msg_son); } close(pipefd2[1]); close(pipefd1[0]); wait(NULL); } return 0; }
代码实现效果:
代码优化:
一、一定要先确定谁先发,谁先收(父进程先发,子进程先收)。
二、.
第一通信:父进程先发,子进程先收
第二通信:
1)父进程先发,子进程先收
我是旦丁
(1:父进程想继续说,子进程继续收 0:父进程不想说了,子进程就可以说了 q:退出)
2)子进程先发,父进程先收 3)结束聊天 三、 close
注意:
子进程和父进程的读写端同一个管道。
简单的避免自己发的信息不要被接受,发送之后可以sleep一下,让别人去接受。
#include <stdio.h> #include <stdlib.h>//exit #include <string.h>//memset #include <errno.h> #include <sys/types.h>//fork #include <sys/wait.h>//wait #include <unistd.h>//fork pipe #define MSG_LENGTH 20 int main() { int pipefd[2]; int pipe_ret = pipe(pipefd); if(pipe_ret == -1) { perror("pipe"); exit(-1); } int pid = fork(); if(pid == -1) { perror("fork"); exit(-1); } else if(pid == 0) { char spreak_mask = '1';//0:父进程不想说话 1:父进程想说话 char msg_data[MSG_LENGTH]; while(1) { memset(msg_data,0,MSG_LENGTH); if(spreak_mask == '0') { printf("请输入要发送给父进程的消息:");//hello scanf("%s",msg_data);//我司旦丁 spreak_mask = msg_data[strlen(msg_data)-1];//更新密令 write(pipefd[1],msg_data,strlen(msg_data));//write sleep(1); } else if(spreak_mask == '1') { //read read(pipefd[0],msg_data,MSG_LENGTH); spreak_mask = msg_data[strlen(msg_data)-1];//更新密令 printf("父进程说:%s\n",msg_data); } else if(spreak_mask == 'q') { break; } else { printf("数据有误,终止通信!\n"); exit(-1); } } } else { char spreak_mask = '1';//0:父进程不想说话 1:父进程想说话 char msg_data[MSG_LENGTH]; while(1) { memset(msg_data,0,MSG_LENGTH); if(spreak_mask == '0') { //read read(pipefd[0],msg_data,MSG_LENGTH); spreak_mask = msg_data[strlen(msg_data)-1];//更新密令 printf("子进程说:%s\n",msg_data); } else if(spreak_mask == '1') { //write printf("请输入要发送给子进程的消息:"); scanf("%s",msg_data); spreak_mask = msg_data[strlen(msg_data)-1];//更新密令 write(pipefd[1],msg_data,strlen(msg_data));//write sleep(1); } else if(spreak_mask == 'q') { break; } else { printf("数据有误,终止通信!\n"); exit(-1); } } } /*共享区域*/ close(pipefd[0]); close(pipefd[1]); if(pid>0) { wait(NULL); } exit(0); }