使用有名管道(FIFO)实现循环通信的客户端-服务端
在 Linux 下,我们可以利用 有名管道(FIFO) 来实现简单的进程间通信(IPC)。本教程将教你如何用 C 写一个 支持循环收发消息的客户端和服务端程序。
一、基础知识回顾:什么是 FIFO?
FIFO(First-In First-Out)是一种有名管道,用于不同进程间单向通信:
- 管道本质是一个特殊文件;
- 打开时如果只有读端或写端会阻塞,直到另一端就绪;
- 用 mkfifo() 创建;
- 与普通文件不同,read()/write() 会阻塞,直到对方准备好。
二、程序结构概览
- 客户端程序 client.c:从键盘读取输入,发给服务,并等待响应。
- 服务器程序 server.c:读取客户端的消息,并回复。
- 使用两个 FIFO 文件:
- fifo_c2s:客户端向服务器发送消息
- fifo_s2c:服务器向客户端发送消息
三、代码实现
3.1 Makefile
Makefile用于自动化构建基于有名管道(FIFO)的简单客户端-服务器通信系统。包含两个可执行目标:server 和 client。
支持 make 编译和 make clean 清理。
CC = gcc # 使用的编译器
CFLAGS = -Wall # 编译器参数:开启全部警告# 默认目标:构建 server 和 client 两个程序
all: server client# 构建 server 程序
server: server.c$(CC) $(CFLAGS) -o server server.c# 构建 client 程序
client: client.c$(CC) $(CFLAGS) -o client client.c# 清理所有生成的目标和中间文件
clean:rm -f server client fifo_c2s fifo_s2c
3.2 服务端代码
基于有名管道(FIFO)的服务器端通信程序。
功能:
- 创建两个命名管道 fifo_c2s 和 fifo_s2c
- 从 fifo_c2s 管道中读取客户端消息
- 向 fifo_s2c 管道中写入回应消息
- 实现循环输入输出,直到终止程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>#define FIFO_C2S "fifo_c2s" // 客户端写 -> 服务端读
#define FIFO_S2C "fifo_s2c" // 服务端写 -> 客户端读int main() {char buffer[1024]; // 存放接收到的消息char reply[1024]; // 存放要发送的回应// 创建 FIFO(如果不存在)mkfifo(FIFO_C2S, 0666);mkfifo(FIFO_S2C, 0666);printf("服务器启动,等待客户端连接...\n");// 打开 FIFO 文件:读和写端int fd_read = open(FIFO_C2S, O_RDONLY);int fd_write = open(FIFO_S2C, O_WRONLY);while (1) {// 从客户端读取数据int n = read(fd_read, buffer, sizeof(buffer) - 1);if (n > 0) {buffer[n] = '\0'; // 添加字符串结尾printf("收到客户端消息: %s\n", buffer);// 构造返回消息snprintf(reply, sizeof(reply), "服务器回应: 收到 [%s]", buffer);// 发送回应给客户端write(fd_write, reply, strlen(reply));}}close(fd_read);close(fd_write);return 0;
}
3.3 客户端代码
基于有名管道(FIFO)的客户端通信程序。
功能:
- 从终端读取用户输入;
- 将输入写入 fifo_c2s 管道发送给服务器
- 从 fifo_s2c 管道读取服务器回应并显示
- 支持循环输入输出直到终止程序。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>#define FIFO_C2S "fifo_c2s" // 客户端写 -> 服务端读
#define FIFO_S2C "fifo_s2c" // 服务端写 -> 客户端读int main() {char buffer[1024]; // 用户输入内容char response[1024]; // 接收服务器回应// 打开 FIFO 文件:写和读端int fd_write = open(FIFO_C2S, O_WRONLY);int fd_read = open(FIFO_S2C, O_RDONLY);printf("客户端启动,可以输入消息...\n");while (1) {printf("你要发送什么:");fflush(stdout);// 从终端读取一行输入if (fgets(buffer, sizeof(buffer), stdin) == NULL)break;// 去除换行符buffer[strcspn(buffer, "\n")] = '\0';// 写入消息到服务器write(fd_write, buffer, strlen(buffer));// 等待并读取服务器回应int n = read(fd_read, response, sizeof(response) - 1);if (n > 0) {response[n] = '\0';printf("收到服务器回应: %s\n", response);}}close(fd_write);close(fd_read);return 0;
}
四、运行步骤
4.1 编译
make
4.2 运行 server(必须先运行)
./server
4.3 运行 client(另开终端)
./client
4.4 交互示例
你可以在客户端不断输入内容,服务器会收到并返回一条处理后的消息。
五 、清理
make clean
这会删除编译出的 server 、client和管道文件 fifo_c2s 、 fifo_s2c