有名管道实现简单聊天程序


1. "你来我往"式简单聊天

函数功能:简单聊天程序,两个程序abab发送信息,b接收信息,ba发送信息,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;
}

程序运行:

最新文章

  1. exe4j的使用
  2. CNC系统实时性分析
  3. 新版Chrome自动禁用第三方插件的解决办法[转]
  4. SSD(Single Shot MultiBox Detector)的安装配置和运行
  5. hadoop 启动停止命令
  6. 关于FileSystemWatcher监听文件创建
  7. 算法 python实现(一) 基本常识
  8. CF 19D 线段树+set压缩坐标轴+离散化map
  9. Git学习05 --分支管理02
  10. c语言libcurl 使用实例get/post方法+c语言字符串处理
  11. [C# 开发技巧]实现属于自己的截图工具
  12. Latex问题收集
  13. px单位html5响应式方案
  14. IDEA中运行KafkaWordCount程序
  15. 保存eclipse个人配置的几种方式
  16. WebStorm 破解方法
  17. Intellij idea常用快捷键和技巧
  18. Deep Learning.ai学习笔记_第三门课_结构化机器学习项目
  19. gogs 源码阅读笔记 001
  20. scrapy-实现下一页请求, scrapy.Request

热门文章

  1. vue3 | slots
  2. vue学习笔记(四)---- 品牌管理案例
  3. linux-基础及相关软件安装
  4. FineUI通过js事件条用后台方法实现弹窗
  5. .NET 支付宝SDK新版 AlipayEasySDK 配置文件详细说明
  6. 这是一篇乖巧的草稿——vscode上传代码到代码托管平台GitHub
  7. Python装饰器实例讲解(三)
  8. python爬虫学习——元组,字典(2.14日博客补)
  9. ideal的基础使用2022版本,黑马程序员的基础使用
  10. TCP/IP协议(9): UDP(User Datagram Protocol) 协议 —— 最简单的传输层协议