【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语 ...
随机推荐
- 无需依赖Docker环境制作镜像
随着高版本的Kubernetes弃用Docker,企业也可以不依赖Docker环境了,但是DevOps通过Kubernetes部署的话,仍然需要制作镜像,那么在没有Docker环境的情况下如何制作呢? ...
- Flink程序打包
在基于 Flink DataStreamAPI 进行流式数据处理应用时,我们可能希望将依赖和应用程序分别打包,如此便于发布和问题定位.在较新版本的 Flink版本中推出了application模式,这 ...
- 【MRTK】HoloLens开发基础项目设置
前言 好记性不如烂笔头,之前做项目的时候很熟练很顺手就没有写笔记.因为排期问题项目中断几个月之后需要重新拾起来,结果发现自己现在忘记得差不多了,于是还是决定写点东西记录一下.即便是简单的项目设置,忘记 ...
- Sentinel入门到实操 (限流熔断降级)
微服务保护--Sentinel 介绍Sentinel 1.背景 Sentinel是阿里巴巴开源的一款微服务流量控制组件.官网地址:https://sentinelguard.io/zh-cn/inde ...
- 随机森林RF模型超参数的优化:Python实现
本文介绍基于Python的随机森林(Random Forest,RF)回归代码,以及模型超参数(包括决策树个数与最大深度.最小分离样本数.最小叶子节点样本数.最大分离特征数等)自动优化的代码. ...
- JZOJ 3213. 【SDOI2013】直径
题目 思路 树的直径很好求,两遍 \(dfs\),记下两个端点 然后很显然所有直径经过的边必然在我们求出的这条直线上 那么我们只要判断一下一条直径上的边是不是答案 假设当前边为 \(i\) 那么把 \ ...
- centos7 ssh服务
转载博客园: Centos7开启SSH服务 - KinwingHU - 博客园 (cnblogs.com)
- js根据指定字段数据去重
//根据id去重 function unique(arr1) { const res = new Map(); return arr1.filter((a) => !res.has(a.id) ...
- 把 URL 中文和一堆百分号转换成字符串
https://www.cnblogs.com/Enziandom/tag/Web%20%E5%BA%94%E7%94%A8%E5%BC%80%E5%8F%91 JS 有解析这样的 URL 的函数,主 ...
- Java中的static关键字作用及其应用
java中的static关键字主要用于内存管理.我们可以应用java static关键字在变量,方法,块和嵌套类中. static关键字属于类,而不是类的实例. static可以是: 1.变量 ...