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;
}
#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;
}