Linux有名管道namepipe --C和Python两种实现方式解析

一:什么是有名管道

不同于管道之处在于它提供一个路径名与之关联,以FIFO的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信(能够访问该路径的进程以及FIFO的创建进程之间),因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进先出(first in first out),对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。就好像把管道的fd[0]和fd[1]变成了两个文件来操作。

二:创建有名管道

有名管道的创建

#include <sys/types.h>

#include <sys/stat.h>

int mkfifo(const char * pathname, mode_t mode)

函数的第一个参数是路径名,第二个参数与打开普通文件的open()函数中的mode参数相同。如果mkfifo的第一个参数是一个已经存在的路径名时,会返回EEXIST错误,所以一般典型的调用代码首先会检查是否返回该错误,如果确实返回该错误,那么只要调用打开FIFO的函数就可以了。一般文件的I/O函数都可以用于FIFO,如closereadwrite等等

Python和C类似,看懂了C的函数,python自然就会了,就是熟悉一下流程而已。

三:C代码如下

头文件:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>

#define MAXLINE 512
#define ERR_EXIT(sz) \
        do{ \
            perror(sz); \
            exit(EXIT_FAILURE); \
        }while(0)

const char* write_fifo = "write_fifo";
const char* read_fifo = "read_fifo";
服务器端:
#include "unp.h"

int main()
{
	int res;
	if(access(read_fifo, F_OK) < 0){     //检测是否存在
		if( (res = mkfifo(write_fifo, O_CREAT|O_EXCL|0755)) < 0)   //创建写fifo,0755为执行权限
			ERR_EXIT("mkfifo err.");
	}
	
	int write_fd;
	if( (write_fd = open(write_fifo, O_WRONLY)) < 0){
		unlink(write_fifo);            //如果失败,删除
		ERR_EXIT("open write_fifo err.");
	}
	
	int read_fd;
	while( (read_fd = open(read_fifo, O_RDONLY)) < 0)   //等待客户端创建读fifo
		sleep(1);
	printf("client connect.\n");

	char sendbuff[MAXLINE];
	char recvbuff[MAXLINE];
	
	for(; ;){
		printf("client:>");
		ssize_t ret;
		if( (ret = read(read_fd, recvbuff, MAXLINE)) < 0)
			ERR_EXIT("read err.");
		printf("%s\n", recvbuff);
		
		printf("server:>");
		scanf("%s", sendbuff);
		write(write_fd, sendbuff, strlen(sendbuff)+1);
	}
	unlink(write_fifo);

	return 0;
}
客户端:
#include "unp.h"

int main()
{
	int res;
	if( (res = mkfifo(read_fifo, O_CREAT|O_EXCL|0755)) < 0)
		ERR_EXIT("mkfifo err.");
	
	int read_fd;
	if( (read_fd = open(write_fifo, O_RDONLY)) < 0)
		ERR_EXIT("open err.");

	int write_fd;
	if( (write_fd = open(read_fifo, O_WRONLY)) < 0){
		unlink(read_fifo);
		ERR_EXIT("open write_fifo err.");
	}

	char sendbuff[MAXLINE];
	char recvbuff[MAXLINE];
	
	ssize_t ret;
	for(; ;){
		printf("client:>");
		scanf("%s", sendbuff);
		if( (ret = write(write_fd, sendbuff, strlen(sendbuff)+1)) < 0)
			ERR_EXIT("write err.");

		printf("server:>");
		read(read_fd, recvbuff, MAXLINE);
		printf("%s\n", recvbuff);
	}

	unlink(read_fifo);

	return 0;
}

四:Python代码如下

服务器端:
import os

name_write = 'write_fifo'
name_read = 'read_fifo'

def main():
	if os.access(name_write, os.F_OK) == False:
		os.mkfifo(name_write)
	
	write_fd = os.open(name_write, os.O_WRONLY)
	read_fd = os.open(name_read, os.O_RDONLY)

	while True:
		out_msg = raw_input('server:>')
		os.write(write_fd, out_msg)
		in_msg = os.read(read_fd, 100)
		print 'client:>' + in_msg
	os.close(write_fd)

if __name__ == '__main__':
	main()
客户端:
import os

name_read = 'write_fifo'
name_write = 'read_fifo'

def main():
	if(os.access(name_write, os.F_OK) == False):
		os.mkfifo(name_write)
	
	read_fd = os.open(name_read, os.O_RDONLY)
	write_fd = os.open(name_write, os.O_WRONLY)
	
	while True:
		in_msg = os.read(read_fd, 100)
		print 'server:>' + in_msg
		out_msg = raw_input('client:>')
		os.write(write_fd, out_msg)
	os.close(read_fd)

if __name__ == '__main__':
	main()

五:结果截图如下



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值