Linux 命名管道

发布于:2025-03-15 ⋅ 阅读:(13) ⋅ 点赞:(0)


在这里插入图片描述

🚀 深入理解命名管道(FIFO)及其C++实现


一、命名管道核心特性

1.1 🧩 基本概念

命名管道(FIFO)是一种特殊的文件类型,具有以下特点:

  • 跨进程通信:允许无亲缘关系进程通信 🌐
  • 文件系统可见:通过mkfifo创建实体文件 📂
  • 双工限制:需分别以读/写模式打开文件描述符 🔄
  • 阻塞特性:打开操作会阻塞直到另一端就绪 ⏳

二、💻 代码实现解析

2.1 📁 公共头文件(common.hpp)

#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define FIFO_FILE "./myfifo"  // 🚪 管道文件路径
#define MODE 0664             // 🔒 权限模式

enum {
    FIFO_CREATE_ERR = 1,     // 🛠️ 创建错误
    FIFO_DELETE_ERR = 2,     // 🗑️ 删除错误
    FIFO_OPEN_ERROR = 3      // 🔓 打开错误
};

class Init {  // 🔄 RAII管理管道生命周期
public:
    Init() {
        int n = mkfifo(FIFO_FILE, MODE);
        if(n == -1) {
            perror("❌ mkfifo");
            exit(FIFO_CREATE_ERR);
        }
    }
    
    ~Init() {
        int m = unlink(FIFO_FILE);
        if(m == -1) {
            perror("❌ unlink");
            exit(FIFO_DELETE_ERR);
        }
    }
};

2.2 🖥️ 服务器端(server.cpp)

#include "common.hpp"

int main() {
    Init init;  // 🏗️ 自动创建管道
    
    int fd = open(FIFO_FILE, O_RDONLY);  // ⏸️ 阻塞直到客户端连接
    if(fd < 0) {
        perror(" open");
        exit(FIFO_OPEN_ERROR);
    }

    cout << " Server ready" << endl;
    
    while(true) {
        char buffer[1024];
        int bytes = read(fd, buffer, sizeof(buffer)-1);
        if(bytes > 0) {
            buffer[bytes] = '\0';
            cout << " Received: " << buffer << endl;
        } else if(bytes == 0) {
            cout << " Client disconnected" << endl;
            break;
        } else {
            perror(" read");
            break;
        }
    }
    close(fd);
    return 0;
}

2.3 📱 客户端(client.cpp)

#include "common.hpp"

int main() {
    int fd = open(FIFO_FILE, O_WRONLY);  // 🔔 触发服务器唤醒
    if(fd < 0) {
        perror(" open");
        exit(FIFO_OPEN_ERROR);
    }

    cout << " Connected to server" << endl;
    
    string line;
    while(getline(cin, line)) {
        write(fd, line.c_str(), line.size());  // 📤 发送数据
    }
    
    close(fd);
    return 0;
}

三、🔧 运行机制图解

Server FIFO Client mkfifo() 🛠️ open(O_RDONLY) ⏳ open(O_WRONLY) 🔔 write() 📤 read() 📥 持续写入 转发数据 loop [🔁 通信循环] close() 🚪 检测EOF 👋 Server FIFO Client

四、💡 技术亮点分析

4.1 🚦 阻塞行为控制

// 服务器端 open() 阻塞示例
int fd = open(FIFO_FILE, O_RDONLY);  // ⏸️

// 客户端 open() 解除阻塞
int fd = open(FIFO_FILE, O_WRONLY);  // ▶️

4.2 ⚡ 数据传输特性

特性 描述 图标
字节流传输 无消息边界,需自定义协议 🌊
原子性保证 小于PIPE_BUF(通常4K)保证原子性 ⚛️
流量控制 写满缓冲区后自动阻塞 🚧

4.3 🐛 错误处理策略

if(write(fd, buf, len) == -1) {
    if(errno == EPIPE) {  // 💔 连接断开
        cout << " Connection closed" << endl;
        close(fd);
        exit(1);
    }
    perror(" write");
}

五、🚀 编译运行演示

5.1 🔧 操作流程

# 终端1:启动服务器
$ ./server
🔄 Server ready

# 终端2:启动客户端
$ ./client
💬 Please Enter@ Hello World!

# 终端1显示
📥 Received: Hello World!


网站公告

今日签到

点亮在社区的每一天
去签到