06 Linux命名管道mkfifo demo

06 Linux命名管道mkfifo demo

作者将狼才鲸
创建日期2023-03-05

  • 运行效果:
jim@ubuntu:/mnt/hgfs/git_win10/many-repositories/22_Linux命名管道Demo$ make
gcc -o server server.c
gcc -o client client.c
jim@ubuntu:/mnt/hgfs/git_win10/many-repositories/22_Linux命名管道Demo$ make run
./server &
sleep 1
waitting for fifo write...
./client
server get[15]: hello world! th
server get[14]: is is string3 h
jim@ubuntu:/mnt/hgfs/git_win10/many-repositories/22_Linux命名管道Demo$ 

  • Makefile:
default:
	gcc -o server server.c
	gcc -o client client.c
run:
	./server &
	sleep 1
	./client
clean:
	rm server client
  • comm.h:
/******************************************************************************
 * \brief	Linux命名管道Demo
 * \remarks	[Linux应用编程---7.有名管道](https://blog.csdn.net/shiyuanxuan369/article/details/128602985)
 *			[Linux系统中mkfifo创建管道后,调用open打开失败,不知道错在哪儿](https://blog.csdn.net/xqhrs232/article/details/53636364)
 * \author	将狼才鲸
 * \date	2023-03-05
 ******************************************************************************/

#ifndef _COMM_H_
#define _COMM_H_

#define FIFO_NAME "/tmp/fifo"

#endif /* _COMM_H_ */

  • server.c:
#include <stdio.h>		/* printf ssize_t */
#include <sys/stat.h>	/* mkfifo */
#include <fcntl.h>		/* open O_RDONLY */
#include <unistd.h>		/* read close */
#include "comm.h"

#define RCV_BUF_SIZE 16
static char rcv_buf[RCV_BUF_SIZE];

/* 先运行server,再运行client;
   client写入端只能open,不能close,否则server会一直阻塞在open中 */

int main()
{
	unlink(FIFO_NAME); /* 先删除有名管道,防止创建不成功 */
	
	/* 创建命名管道,创建的目录不能在Windows下的共享文件夹中,也不能是~/xxx */
	int ret = mkfifo(FIFO_NAME, 0664);
	if (ret < 0) {
		printf("make fifo '%s' error %d\n", FIFO_NAME, ret);
		perror("perror");	/* 如果发生了错误,则打印具体的错误提示 */
		return -1;
	}

	printf("waitting for fifo write...\n");

	/* 用只读的方式打开命名管道;
	   本读取端必须先打开,否则client写入端的open会一直阻塞*/
	int fd = open(FIFO_NAME, O_RDONLY);
	if (fd < 0) {
		printf("server open fifo error\n");
		return -1;
	}

	while (1) {
		/* 读取指定长度的内容,如果未读满则返回已读的长度,如果无数据可读则返回0,不阻塞 */
		ssize_t len = read(fd, rcv_buf, sizeof(rcv_buf) - 1);
		if (len < 0) {
			printf("server read error\n");
			goto exit;
		}

		/* 打印读到的字符串 */
		if (len > 0) {
			rcv_buf[RCV_BUF_SIZE - 1] = '\0';
			printf("server get[%d]: %s\n", len, rcv_buf);
		}
	}

exit:
	close(fd);
	unlink(FIFO_NAME); /* 删除有名管道 */

	return 0;
}

  • client.c:
#include <stdio.h>	/* printf ssize_t */
#include <fcntl.h>	/* open O_RDONLY */
#include <unistd.h>	/* write close */
#include <string.h>	/* strlen */
#include "comm.h"

#define WRITE_STRING1 "hello world! "
#define WRITE_STRING2 "this is "
#define WRITE_STRING3 "string3 "

int main()
{
	/* 用只写的方式打开命名管道;要先运行server,在运行此client;
	   只有当server的读模式打开时才返回,否则会一直阻塞 */
	int fd = open(FIFO_NAME, O_WRONLY);
	if (fd < 0) {
		printf("client open fifo error\n");
		return -1;
	}

	/* 向命名管道写数据 */
	write(fd, WRITE_STRING1, strlen(WRITE_STRING1));
	write(fd, WRITE_STRING2, strlen(WRITE_STRING2));
	write(fd, WRITE_STRING3, strlen(WRITE_STRING3));

	/* 不能close(),如果close了server端会一直阻塞在open()中 */

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值