管道
所有式样的UNIX都提供管道。它由pipe函数创建。提供一个单路(单向)数据流。
函数原型:
#include
int pipe(int fd[2])
该函数返回两个文件描述符:fd[0]和fd[1]。前者打开来读,后者打开来写。
下面给出一个简单的客户端和服务器例子。main函数创建两个管道并用fork生成一个子进程。客户然后作为父进程运行,服务器作为子进程运行,第一个管道用于从客户端向服务器发送路径名,第二个管道用于从服务器向客户端发送该文件的内容。
其大概的布局如图:
我们先给出main函数:
#include"uitil.h"
int main(int argc,char*argv[])
{
int pipe1[2],pipe2[2];
pid_t pid;
int res1;
int res2;
//创建管道
res1 = pipe(pipe1);
if(res1 == -1){
cout << "pipe error." << endl;
exit(1);
}
res2 = pipe(pipe2);
if(res2 == -1){
cout << "pipe error." << endl;
exit(1);
}
//fork用于创建一个子进程
pid = fork();
if(pid == 0){
cout << "child." << endl;
//child
//子进程从管道1中读数据,写到管道2中
close(pipe1[1]);
close(pipe2[0]);
server(pipe1[0],pipe2[1]);
exit(0);
}else if(pid > 0){
cout << "parent." << endl;
//father
//父进程从管道2中读数据,写到管道1中
close(pipe1[0]);
close(pipe2[1]);
client(pipe2[0],pipe1[1]);
waitpid(pid,NULL,0);
exit(0);
}else{
cout << "fork error." << endl;
exit(1);
}
return 0;
}
void client(int readfd,int writefd)
{
size_t len;
ssize_t n;
char buff[MAXLINE];
//char *fgets(char*buf,int bufsize,FILE* stream)
//参数
// *buf:字符型指针,指向用来存储所的数据的地址
// bufsize:整型数据,指明存储数据的大小
// *stream:文件结构体指针,将要读取的文件流
//返回值:
// 1.成功,则返回第一个参数buf
// 2.在读字符时遇到end-of-file,则eof指示器被设置,
// 如果还没读入任何字符就遇到这种情况,则buf保持原来的内容,返回NULL
// 3.如果发生读入错误,error指示器被设置,返回NULL,buf的值可能被改变
//stdin代表输入的路径名
fgets(buff,MAXLINE,stdin);
len = strlen(buff);
if(buff[len - 1] == '\n')
len--;
//将路径名写入到管道1
write(writefd,buff,len);
//客户端从管道2中读取文件的内容
while((n = read(readfd,buff,MAXLINE)) > 0){
write(STDOUT_FILENO,buff,n);
}
}
void server(int readfd,int writefd)
{
int fd;
ssize_t n;
char buff[MAXLINE + 1];
// ssize_t read(int fd,void* buf,size_t nbytes)
// 把参数fd所指的文件的nbyte个字节读到buf指针所指的内存,
// 若nbytes为0,则read()不会有作用并返回0;
// 返回值为实际读取到的字节数,返回0表示已到达文件尾或无可取的数据,错误返回-1
// 并将根据不同的错误原因适当的设置错误码
//服务器从管道1中读取路径名
n = read(readfd,buff,MAXLINE);
if(n == 0){
cout << "end_of_file while reading pathname." << endl;
exit(1);
}
buff[n] = '\0';
//以只读方式打开文件
fd = open(buff,O_RDONLY);
if(fd < 0){
snprintf(buff + n,sizeof(buff) - n,":cant't open ,%s\n",strerror(errno));
n = strlen(buff);
write(writefd,buff,n);
}else{
//当服务器打开文件成功时,将文件的内容写入到管道2
while((n = read(fd,buff,MAXLINE)) > 0){
write(writefd,buff,n);
}
//关闭文件
close(fd);
}
}
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXLINE 4096
using namespace std;
打开一个已存在的文件test,服务器将返回文件test的内容
打开一个不存在的文件时,将提示错误!!!