Linux--管道

1. 无名管道,只适用于有亲缘关系的进程之间通信

#include <stdio.h>
#include <fcntl.h>              /* Obtain O_* constant definitions */
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

#define MAX_PATH 255
/*
	server: 接受客户端发送过来的下载文件请求,如果文件存在,则直接把数据发送给客户端
	如果文件不存在,则返回出错信息给客户端
*/
void server(int fdCtrl, int fdData)
{
	char fileName[MAX_PATH] = {0};
	ssize_t size = 0;
	size = read(fdCtrl, fileName, sizeof(fileName));
	if (size == 0)
	{
		printf("end of file read\n");
		return;
	}
	
	int fd;
	
	if ((fd = open(fileName, O_RDONLY)) < 0)
	{
		write(fdData, "no such file\n", strlen("no such file\n"));
	}
	else
	{
		char line[1024] = {0};
		while((size = read(fd, line, sizeof(line))) > 0)
		{
			write(fdData, line, strlen(line));
			memset(line, 0x0, sizeof(line));
		}
		close(fd);
	}
}

/*
	client: 从标准输入键入一个文件名,然后等待服务器那端把数据传输过来
*/

void client(int fdCtrl, int fdData)
{
	char fileName[MAX_PATH] = {0};
	
	printf("please input a file:");
	fgets(fileName, sizeof(fileName), stdin);
	
	if (fileName[strlen(fileName) - 1] == '\n')
	{
		fileName[strlen(fileName) - 1] = 0;
	}
	
	write(fdCtrl, fileName, strlen(fileName));
	//close(fdCtrl);
	
	ssize_t size = 0;
	char line[1024] = {0};
	while((size = read(fdData, line, sizeof(line))) > 0)
	{
		write(STDOUT_FILENO, line, size);
		memset(line, 0x0, sizeof(line));
	}
	if (size == 0)
	{
		printf("transfer over!!!\n");
	}
}

int main(int argc, char **argv)
{
	int fdCtrl[2];
	int fdData[2];
	pid_t pid;
	
	//控制管道
	if (pipe(fdCtrl) < 0)
	{
		perror("pipe");
		return -1;
	}
	
	//文件管道
	if (pipe(fdData) < 0)
	{
		perror("pipe");
		return -1;
	}
	
	if ((pid = fork()) < 0)
	{
		perror("fork");
		return -1;
	}
	else if (pid == 0) //child -- server
	{
		close(fdCtrl[1]);
		close(fdData[0]);
		
		server(fdCtrl[0], fdData[1]);
		close(fdCtrl[0]);
		close(fdData[1]);
		exit(0);
	}
	else //parent -- client
	{
		close(fdCtrl[0]);
		close(fdData[1]);
		
		client(fdCtrl[1], fdData[0]);
		
		waitpid(pid, NULL, 0);
		close(fdCtrl[1]);
		close(fdData[0]);
		exit(0);
	}
	return 0;
}


2. 有名管道,适用于有亲缘和非亲缘关系的进程,下面例子是亲缘关系间使用

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

#define FIFO1 "/tmp/control_fifo"
#define FIFO2 "/tmp/data_fifo"
#define FILE_MODE (S_IRUSR |S_IWUSR | S_IRGRP | S_IROTH)
#define ERROR_MSG "cannot find this file\n"
#define MAX_PATH 255

/*
	server: get the file name, then write the data to client, if the file not exists, then
	write error info to client
*/
void server(int readfd, int writefd)
{
	char fileName[MAX_PATH] = {0};
	read(readfd, fileName, sizeof(fileName));
	
	int fd = open(fileName, O_RDONLY);
	if (fd < 0)
	{
		write(writefd, ERROR_MSG, strlen(ERROR_MSG));
		return ;
	}
	else
	{
		ssize_t size = 0;
		char line[1024] = {0};
		while((size = read(fd, line, sizeof(line))) > 0)
		{
			write(writefd, line, size);
		}
	}
}

/*
	client: input the file name, transfer to server, then wait to read data
*/

void client(int writefd, int readfd)
{
	char fileName[MAX_PATH] = {0};
	printf("please input a file: ");
	scanf("%s", fileName);
	
	write(writefd, fileName, strlen(fileName));
	
	ssize_t size = 0;
	char line[1024] = {0};
	while((size = read(readfd, line, sizeof(line))) > 0 )
	{
		write(STDOUT_FILENO, line, size);
	}
	
	if (size == 0)
	{
		write(STDOUT_FILENO, "transfer over!!!\n", 18);
	}
}

int main(int argc, char *argv[])
{
	pid_t pid;
	int readfd, writefd;
	
	if (mkfifo(FIFO1, FILE_MODE) < 0 && errno != EEXIST)
	{
		perror("mkfifo");
		return -1;
	}
	
	if (mkfifo(FIFO2, FILE_MODE) < 0 && errno != EEXIST)
	{
		perror("mkfifo");
		return -1;
	}
	
	if ((pid = fork()) == 0)
	{
		readfd = open(FIFO1, O_RDONLY);
		writefd = open(FIFO2, O_WRONLY);
		server(readfd, writefd);
		
		close(readfd);
		close(writefd);
	}
	else if(pid > 0)
	{
		writefd = open(FIFO1, O_WRONLY);
		readfd = open(FIFO2, O_RDONLY);
		client(writefd, readfd);
		
		waitpid(pid, NULL, 0);
		close(writefd);
		close(readfd);
		
		unlink(FIFO1);
		unlink(FIFO2);
	}
	else
	{
		printf("fork error\n");
		return -1;
	}
	//int mkfifo(const char *pathname, mode_t mode);
	return 0;
}





3. 非亲缘关系进程间通信

fifo_read.c

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

#define FIFO1 "/tmp/control_fifo"
#define FILE_MODE (S_IRUSR |S_IWUSR | S_IRGRP | S_IROTH)
#define ERROR_MSG "cannot find this file\n"
#define MAX_PATH 255

int main(int argc, char *argv[])
{
	int fd;
	
	if (mkfifo(FIFO1, FILE_MODE) < 0 && errno != EEXIST)
	{
		perror("mkfifo");
		return -1;
	}
	
	fd = open(FIFO1, O_RDONLY);
	if (fd < 0)
	{
		perror("open");
		return -1;
	}
	
	ssize_t size = 0;
	char line[1024] = {0};
	if ((size = read(fd, line, sizeof(line))) > 0)
	{
		write(STDOUT_FILENO, line, size);
	}
	
	return 0;
}

fifo_write.c

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

#define FIFO1 "/tmp/control_fifo"
#define FILE_MODE (S_IRUSR |S_IWUSR | S_IRGRP | S_IROTH)
#define ERROR_MSG "cannot find this file\n"
#define MAX_PATH 255

int main(int argc, char *argv[])
{
	int fd;
	
	if (mkfifo(FIFO1, FILE_MODE) < 0 && errno != EEXIST)
	{
		perror("mkfifo");
		return -1;
	}
	
	fd = open(FIFO1, O_WRONLY);
	if (fd < 0)
	{
		perror("open");
		return -1;
	}
	
	ssize_t size = 0;
	char line[1024] = {"gzhang love zhengcx\n"};
	if ((size = write(fd, line, strlen(line))) > 0)
	{
		printf("transfer over!\n");
	}
	
	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值