【Linux】有名管道实现进程间通信——一个简单聊天程序
有名管道实现简单聊天程序
1. "你来我往"式简单聊天
函数功能:简单聊天程序,两个程序a和b,a向b发送信息,b接收信息,b向a发送信息,a接收信息;...

源码参考:
chatA.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main()
{
char *fifo1 = "fifo1";
char *fifo2 = "fifo2";
// 1. 判断有名管道文件是否存在
int ret = access(fifo1, F_OK);
if (ret == -1)
{
// 文件不存在,需要创建
printf("%s文件不存在,创建管道\n", fifo1);
ret = mkfifo(fifo1, 0664);
if (ret == -1)
{
perror("mkfifo");
exit(-1); // 退出
}
}
ret = access(fifo2, F_OK);
if (ret == -1)
{
// 文件不存在,需要创建
printf("%s文件不存在,创建管道\n", fifo2);
ret = mkfifo(fifo2, 0664);
if (ret == -1)
{
perror("mkfifo");
exit(-1); // 退出
}
}
// 2. 以只写方式打开管道1
int fdw = open(fifo1, O_WRONLY);
if (fdw == -1)
{
perror("open");
exit(-1);
}
printf("只写方式打开fifo1成功,等待写入数据...\n");
// 以只读方式打开管道2
int fdr = open(fifo2, O_RDONLY);
if (fdr == -1)
{
perror("open");
exit(-1);
}
printf("只读方式打开fifo2成功,等待读取数据...\n");
// 3. 循环写读数据
char buf[256];
while (1)
{
memset(buf, 0, sizeof(buf));
// 获取标准输入的数据,使用fgets()函数
fgets(buf, sizeof(buf), stdin);
// 写数据到fifo1
int len = write(fdw, buf, strlen(buf));
if (len == -1)
{
perror("write");
break;
}
// 读管道数据
memset(buf, 0, sizeof(buf));
len = read(fdr, buf, sizeof(buf));
if (len <= 0)
{
perror("read");
break;
}
printf("buf : %s\n", buf);
}
// 关闭文件描述符
close(fdr);
close(fdw);
return 0;
}
chatB.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main()
{
char *fifo1 = "fifo1";
char *fifo2 = "fifo2";
// 1. 判断有名管道文件是否存在
int ret = access(fifo1, F_OK);
if (ret == -1)
{
// 文件不存在,需要创建
printf("%s文件不存在,创建管道\n", fifo1);
ret = mkfifo(fifo1, 0664);
if (ret == -1)
{
perror("mkfifo");
exit(-1); // 退出
}
}
ret = access(fifo2, F_OK);
if (ret == -1)
{
// 文件不存在,需要创建
printf("%s文件不存在,创建管道\n", fifo2);
ret = mkfifo(fifo2, 0664);
if (ret == -1)
{
perror("mkfifo");
exit(-1); // 退出
}
}
// 2. 以只读方式打开管道1
int fdr = open(fifo1, O_RDONLY);
if (fdr == -1)
{
perror("open");
exit(-1);
}
printf("只读方式打开fifo1成功,等待读取数据...\n");
// 以只写方式打开管道2
int fdw = open(fifo2, O_WRONLY);
if (fdw == -1)
{
perror("open");
exit(-1);
}
printf("只写方式打开fifo2成功,等待写入数据...\n");
// 3. 循环读写数据
char buf[256];
while (1)
{
// 读管道数据
memset(buf, 0, sizeof(buf));
int len = read(fdr, buf, sizeof(buf));
if (len <= 0)
{
perror("read");
break;
}
printf("buf : %s\n", buf);
memset(buf, 0, sizeof(buf));
// 获取标准输入的数据,使用fgets()函数
fgets(buf, sizeof(buf), stdin);
// 写数据到fifo1
len = write(fdw, buf, strlen(buf));
if (len == -1)
{
perror("write");
break;
}
}
// 关闭文件描述符
close(fdr);
close(fdw);
return 0;
}
程序运行:

2. "喋喋不休"式简单聊天
上面的程序不能实现一方一直给另一方发送信息,可以把读写功能分别放在不同的进程中,比如放在父子进程中分别对读写进行操作。

参考代码:
newChatA.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main()
{
// 1. 创建子进程
pid_t pid = fork();
if (pid > 0)
{
// 父进程, 写FIFO1
char *fifo1 = "fifo1";
// 2. 判断有名管道文件是否存在
int ret = access(fifo1, F_OK);
if (ret == -1)
{
// 文件不存在,需要创建
printf("%s文件不存在,创建管道\n", fifo1);
ret = mkfifo(fifo1, 0664);
if (ret == -1)
{
perror("mkfifo");
exit(-1); // 退出
}
}
// 3. 以只写方式打开 FIFO1
int fdw = open(fifo1, O_WRONLY);
if (fdw == -1)
{
perror("open");
exit(-1);
}
printf("只写方式打开fifo1成功,等待写入数据...\n");
// 4. 循环写入数据
char buf[256];
while (1)
{
memset(buf, 0, sizeof(buf));
// 获取标准输入的数据,使用fgets()函数
fgets(buf, sizeof(buf), stdin);
// 写数据到fifo1
int len = write(fdw, buf, strlen(buf));
if (len == -1)
{
perror("write");
break;
}
}
close(fdw);
}
else if (pid == 0)
{
// 子进程 读FIFO2
char *fifo2 = "fifo2";
int ret = access(fifo2, F_OK);
if (ret == -1)
{
// 文件不存在,需要创建
printf("%s文件不存在,创建管道\n", fifo2);
ret = mkfifo(fifo2, 0664);
if (ret == -1)
{
perror("mkfifo");
exit(-1); // 退出
}
}
// 以只读方式打开 FIFO2
int fdr = open(fifo2, O_RDONLY);
if (fdr == -1)
{
perror("open");
exit(-1);
}
printf("只读方式打开fifo2成功,等待读取数据...\n");
// 循环读数据
char buf[256];
while (1)
{
// 读管道数据
memset(buf, 0, sizeof(buf));
int len = read(fdr, buf, sizeof(buf));
if (len <= 0)
{
perror("read");
break;
}
printf("buf : %s\n", buf);
}
close(fdr);
}
return 0;
}
newChatB.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
int main()
{
// 1. 创建子进程
pid_t pid = fork();
if (pid > 0)
{
// 父进程, 写FIFO2
char *fifo2 = "fifo2";
// 2. 判断有名管道文件是否存在
int ret = access(fifo2, F_OK);
if (ret == -1)
{
// 文件不存在,需要创建
printf("%s文件不存在,创建管道\n", fifo2);
ret = mkfifo(fifo2, 0664);
if (ret == -1)
{
perror("mkfifo");
exit(-1); // 退出
}
}
// 3. 以只写方式打开 FIFO2
int fdw = open(fifo2, O_WRONLY);
if (fdw == -1)
{
perror("open");
exit(-1);
}
printf("只写方式打开fifo2成功,等待写入数据...\n");
// 4. 循环写入数据
char buf[256];
while (1)
{
memset(buf, 0, sizeof(buf));
// 获取标准输入的数据,使用fgets()函数
fgets(buf, sizeof(buf), stdin);
// 写数据到fifo1
int len = write(fdw, buf, strlen(buf));
if (len == -1)
{
perror("write");
break;
}
}
close(fdw);
}
else if (pid == 0)
{
// 子进程 读FIFO1
char *fifo1 = "fifo1";
int ret = access(fifo1, F_OK);
if (ret == -1)
{
// 文件不存在,需要创建
printf("%s文件不存在,创建管道\n", fifo1);
ret = mkfifo(fifo1, 0664);
if (ret == -1)
{
perror("mkfifo");
exit(-1); // 退出
}
}
// 以只读方式打开 FIFO1
int fdr = open(fifo1, O_RDONLY);
if (fdr == -1)
{
perror("open");
exit(-1);
}
printf("只读方式打开fifo1成功,等待读取数据...\n");
// 循环读数据
char buf[256];
while (1)
{
// 读管道数据
memset(buf, 0, sizeof(buf));
int len = read(fdr, buf, sizeof(buf));
if (len <= 0)
{
perror("read");
break;
}
printf("buf : %s\n", buf);
}
close(fdr);
}
return 0;
}
程序运行:

【Linux】有名管道实现进程间通信——一个简单聊天程序的更多相关文章
- Python使用Socket写一个简单聊天程序
b2b模式的聊天工具 服务端: # 链接 while True: print('等待连接...') sock,adr = server_socket.accept() while True: try: ...
- linux 有名管道(FIFO)
http://blog.csdn.net/firefoxbug/article/details/8137762 linux 有名管道(FIFO) 管道的缓冲区是有限的(管道制存在于内存中,在管道创建时 ...
- Linux有名管道的 阻塞VS非阻塞 读写
参考文章: 关于有名管道open时阻塞的问题 Linux有名管道(FIFO)的阻塞和非阻塞读写 挖坑,日后填
- 关于SIGSLOT的一个简单的程序
废话少说直接看代码即可,这只是一个简单的程序,可以帮我们简单地明白SIGSLOT是怎么回事.至于深入研究自己去百度吧. #include "sigslot.h" using nam ...
- Linux内核分析:完成一个简单的时间片轮转多道程序内核代码
PS.贺邦 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 1.m ...
- Android 网络编程基础之简单聊天程序
前一篇讲了Android的网络编程基础,今天写了一个简单的聊天程序分享一下 首先是服务端代码: package com.jiao.socketdemo; import java.io.Buffered ...
- websocket实现简单聊天程序
程序的流程图: 主要代码: 服务端 app.js 先加载所需要的通信模块: var express = require('express'); var app = express(); var htt ...
- 利用 Linux tap/tun 虚拟设备写一个 ICMP echo 程序
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 前面两篇文章已 ...
- C#一个简单下载程序实例(可用于更新)
运行时的界面 using System; using System.Collections.Generic; using System.ComponentModel; using System.Dat ...
- 关于Hibernate的一个简单小程序
本人根据视频学习了一下三大框架中比较简单的一个Hibernate,并简单完成了一个运用Hibernate的小程序 Hibernate是一个简化web程序Dao层的一个框架,应用他,可以完全脱离sql语 ...
随机推荐
- ubuntu20.04 gnome桌面系统添加开机自启动GUI程序
在终端执行 gnome-session-properties,点击添加自己的脚本或执行文件,便可以在用户登录后自动执行.
- Solon v2.0 大版本发布。提效率!降成本!
一个高效的 Java 应用开发框架:更快.更小.更简单.不是 Spring,没有 Servlet,也无关 JavaEE:新兴独立的开放生态.主框架仅 0.1 MB. 150来个生态插件,覆盖各种不同的 ...
- Element-Ui表单移除校验clearValidate和resetFields
添加和修改公用一个弹窗,点击添加弹窗后,如果没移除表单校验的话,再点击修改弹窗时校验就会被记住,所以需要移除校验,但在清空表单校验时会报如下错误: 那么,你只需要加上这段话即可 this.$nextT ...
- 5.安装&卸载子应用 投票
另起一个新的Django项目 djangoProject_poll_test ........ 把.tar.gz包下载到某个路径 D:\此电脑下分类\桌面\django-polls\dist\djan ...
- NETAPP硬盘更换
netapp硬盘新增 一.找到坏盘,插上新盘# 1.登陆到想要点亮的硬盘相对应的控制器上,并进去高级模式. priv set advanced 2.利用disk show -v 查看想要点亮的硬盘名字 ...
- 滴水 1.c++类 this指针 笔记+指针
1.结构体带参数传递 将结构体的数据压入堆栈中 然后进入函数内进行处理 2.结构体指针传递 将this指针压入进去 来查找 a b数据 3.函数可以放在结构体里面,也可以放在结构体外面 放入进去后 但 ...
- 分布式共识算法随笔 —— 从 Quorum 到 Paxos
分布式共识算法随笔 -- 从 Quorum 到 Paxos 本文主要参考各类英文文献,部分专业术语翻译较为生硬,望谅解. 概览: 为什么需要共识算法? 昨夜西风凋碧树,独上高楼,望尽天涯路 复制(Re ...
- JZOJ 4289.Mancity
\(Mancity\) \(Description\) \(Input\) \(Output\) \(Sample Input\) 8 3 6 1 2 1 1 3 2 4 2 5 1 6 1 6 2 ...
- LeetCode-1994 好子集的数目
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/the-number-of-good-subsets 题目描述 给你一个整数数组 nums .如果 ...
- LeetCode-1765 地图中的最高点
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/map-of-highest-peak 题目描述 给你一个大小为 m x n 的整数矩阵 isWa ...