管道的本质是一种文件,通常是指把一个进程的输出直接传递给另一个进程的输入。
命名管道(named pipe)是一种特殊的文件类型(FIFO文件),它在文件系统中以文件名的形式存在。
下面是Linux中命名管道的文件格式:
通过命令行创建命名管道可以通过mkfifo命令,函数调用如下所示:
1 #include <sys/types.h> 2 #include <sys/stat.h> 3 4 int mkfifo(const char *filename,mode_t mode);
了解以上概念后,我们可以通过open(),read(),write(),close()实现简单的聊天程序,
但需要注意的是当没有数据可读时,read调用通常会阻塞,即它将暂停进程来等待直到有数据达到为止。
对于一个已关闭写数据的管道做read调用将返回0而不是阻塞,这与读取一个无效的文件描述符不同,
read把无效的文件描述符看作一个错误并返回-1。
接下来为大家展示一下利用两个命名管道实现简单聊天程序^_^
进程一:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<sys/types.h> 5 #include<sys/stat.h> 6 #include<fcntl.h> 7 #include<unistd.h> 8 9 int main(int argc,char* argv[]) 10 {//c1->cl2 cl2->cl1 11 int fd_send=open(argv[1],O_WRONLY); 12 int fd_recv=open(argv[2],O_RDONLY); 13 if(-1==fd_send||-1==fd_recv) 14 { 15 perror("open"); 16 exit(1); 17 } 18 printf("ok!\n"); 19 char buf[1024]; 20 while(memset(buf,0,1024),read(0,buf,1024)!=0) 21 { 22 write(fd_send,buf,strlen(buf)); 23 printf("begin read from pipe...\n"); 24 memset(buf,0,1024); 25 read(fd_recv,buf,1024); 26 printf("from cl2:%s",buf); 27 } 28 close(fd_send); 29 close(fd_recv); 30 printf("pipe exit!\n"); 31 return 0;
进程二:
1 int main(int argc,char* argv[]) 2 {//cl2->cl1 cl1->cl2 3 int fd_recv=open(argv[2],O_RDONLY); 4 int fd_send=open(argv[1],O_WRONLY); 5 if(-1==fd_send||-1==fd_recv) 6 { 7 perror("open"); 8 exit(1); 9 } 10 printf("ok!\n"); 11 char buf[1024]; 12 while(printf("begin read from pipe...!\n"), memset(buf,0,1024),read(fd_recv,buf,1024)!=0) 13 { 14 printf("from cl1:%s",buf); 15 memset(buf,0,1024); 16 read(0,buf,1024); 17 write(fd_send,buf,strlen(buf)); 18 } 19 close(fd_send); 20 close(fd_recv); 21 printf("pipe exit!\n"); 22 return 0; 23 }
效果如图:
时间: 2024-11-09 13:48:46