【Linux】有名管道实现进程间通信——一个简单聊天程序
2024-10-10 14:30:10
有名管道实现简单聊天程序
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;
}
程序运行:
最新文章
- exe4j的使用
- CNC系统实时性分析
- 新版Chrome自动禁用第三方插件的解决办法[转]
- SSD(Single Shot MultiBox Detector)的安装配置和运行
- hadoop 启动停止命令
- 关于FileSystemWatcher监听文件创建
- 算法 python实现(一) 基本常识
- CF 19D 线段树+set压缩坐标轴+离散化map
- Git学习05 --分支管理02
- c语言libcurl 使用实例get/post方法+c语言字符串处理
- [C# 开发技巧]实现属于自己的截图工具
- Latex问题收集
- px单位html5响应式方案
- IDEA中运行KafkaWordCount程序
- 保存eclipse个人配置的几种方式
- WebStorm 破解方法
- Intellij idea常用快捷键和技巧
- Deep Learning.ai学习笔记_第三门课_结构化机器学习项目
- gogs 源码阅读笔记 001
- scrapy-实现下一页请求, scrapy.Request
热门文章
- vue3 | slots
- vue学习笔记(四)---- 品牌管理案例
- linux-基础及相关软件安装
- FineUI通过js事件条用后台方法实现弹窗
- .NET 支付宝SDK新版 AlipayEasySDK 配置文件详细说明
- 这是一篇乖巧的草稿——vscode上传代码到代码托管平台GitHub
- Python装饰器实例讲解(三)
- python爬虫学习——元组,字典(2.14日博客补)
- ideal的基础使用2022版本,黑马程序员的基础使用
- TCP/IP协议(9): UDP(User Datagram Protocol) 协议 —— 最简单的传输层协议