• 【操作系统】操作系统课后作业-聊天程序


    无名管道与有名管道的区别

    无名管道

    它是半双工的,具有固定的读端和写端。

    只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。

    不是普通的文件,不属于其他任何文件系统,并且只存在于内存中。

    有名管道FIFO

    FIFO可以在无关的进程之间交换数据。

    FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。

    思路

    父进程负责写,子进程负责读。

    FIFO1负责存储用户a发出的消息,

    FIFO2负责存储用户b发出的消息。

    代码

    chat_a.c

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. int main(){
    9. pid_t pid = fork();
    10. if (pid > 0)
    11. {
    12. //a的父进程写FIFO1
    13. char *fifo1 = "./fifo1";
    14. //判断fifo1是否存在
    15. int ret = access(fifo1, F_OK);
    16. if (ret == -1){
    17. //文件不存在,需要创建
    18. ret = mkfifo(fifo1, 0664);
    19. if (ret == -1){
    20. //创建失败
    21. perror("mkfifo error");
    22. exit(-1);
    23. }
    24. }
    25. //文件fifo1存在,以只写方式打开
    26. int fdw = open(fifo1, O_WRONLY);
    27. if (fdw == -1)
    28. {
    29. perror("open error");
    30. exit(-1);
    31. }
    32. printf("a:successfully opened fifo1\n");
    33. //循环写入数据
    34. char buf[256];
    35. while (1){
    36. memset(buf, 0, sizeof(buf));
    37. //获取标准输入的数据
    38. fgets(buf, sizeof(buf), stdin);
    39. //写数据到fifo1
    40. int len = write(fdw, buf, strlen(buf));
    41. if (len == -1){
    42. perror("write error");
    43. break;
    44. }
    45. printf("\n");
    46. }
    47. close(fdw);
    48. }
    49. else if (pid == 0)
    50. {
    51. //a的子进程读FIFO2
    52. char *fifo2 = "./fifo2";
    53. //判断FIFO2是否存在
    54. int ret = access(fifo2, F_OK);
    55. if (ret == -1)
    56. {
    57. //文件不存在,需要创建
    58. ret = mkfifo(fifo2, 0664);
    59. if (ret == -1)
    60. {
    61. //创建失败
    62. perror("mkfifo error");
    63. exit(-1);
    64. }
    65. }
    66. //文件FIFO2存在,以只读方式打开
    67. int fdr = open(fifo2, O_RDONLY);
    68. if (fdr == -1)
    69. {
    70. perror("open error");
    71. exit(-1);
    72. }
    73. printf("a:successfully opened fifo2\n");
    74. //循环读数据
    75. char buf[256];
    76. while (1)
    77. {
    78. memset(buf, 0, sizeof(buf));
    79. int len = read(fdr, buf, sizeof(buf));
    80. if (len <= 0)
    81. {
    82. perror("read");
    83. break;
    84. }
    85. printf("b: %s\n", buf);
    86. }
    87. close(fdr);
    88. }
    89. return 0;
    90. }

    chat_b.c

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. int main(){
    9. pid_t pid = fork();
    10. if (pid > 0){
    11. //b的父进程写FIFO2
    12. char *fifo2 = "./fifo2";
    13. //判断文件fifo2是否存在
    14. int ret = access(fifo2, F_OK);
    15. if (ret == -1)
    16. {
    17. //文件不存在,需要创建
    18. ret = mkfifo(fifo2, 0664);
    19. if (ret == -1)
    20. {
    21. perror("mkfifo error");
    22. exit(-1);
    23. }
    24. }
    25. //文件fifo2存在,以只写方式打开
    26. int fdw = open(fifo2, O_WRONLY);
    27. if (fdw == -1)
    28. {
    29. perror("open error");
    30. exit(-1);
    31. }
    32. printf("b:successfully opened fifo2\n");
    33. //循环写入数据
    34. char buf[256];
    35. while (1)
    36. {
    37. memset(buf, 0, sizeof(buf));
    38. //获取标准输入的数据
    39. fgets(buf, sizeof(buf), stdin);
    40. //写数据到fifo2
    41. int len = write(fdw, buf, strlen(buf));
    42. if (len == -1)
    43. {
    44. perror("write error");
    45. break;
    46. }
    47. printf("\n");
    48. }
    49. close(fdw);
    50. }
    51. else if (pid == 0)
    52. {
    53. //b的子进程读FIFO1
    54. char *fifo1 = "./fifo1";
    55. int ret = access(fifo1, F_OK);
    56. if (ret == -1)
    57. {
    58. //文件不存在,需要创建
    59. ret = mkfifo(fifo1, 0664);
    60. if (ret == -1)
    61. {
    62. perror("mkfifo error");
    63. exit(-1);
    64. }
    65. }
    66. //文件FIFO1存在,以只读方式打开
    67. int fdr = open(fifo1, O_RDONLY);
    68. if (fdr == -1)
    69. {
    70. perror("open error");
    71. exit(-1);
    72. }
    73. printf("b:successfully opened fifo1\n");
    74. // 循环读数据
    75. char buf[256];
    76. while (1)
    77. {
    78. memset(buf, 0, sizeof(buf));
    79. int len = read(fdr, buf, sizeof(buf));
    80. if (len <= 0)
    81. {
    82. perror("read");
    83. break;
    84. }
    85. printf("a: %s\n", buf);
    86. }
    87. close(fdr);
    88. }
    89. return 0;
    90. }
  • 相关阅读:
    Function 源码解析与实践
    【Linux】NFS服务器搭建配置挂载(Linux挂载Windows目录)
    想发EI国际学术会议,但学校要求知网,这种情况该如何解决?
    动画的js动画于css3区别?
    10月TIOBE榜Java跌出前三!要不我转回C#吧
    27岁自学Python转行靠谱吗?入行晚吗?
    软件测试之编写用例的重要性
    Flutter基础组件:开关、进度组件、图片组件、图标组件
    java计算机毕业设计大学生兼职网站源码+系统+lw文档+mysql数据库+部署
    Java开发 - 探寻Spring的秘密
  • 原文地址:https://blog.csdn.net/weixin_52553215/article/details/139798410