首页 > 代码库 > 利用命名管道实现进程间的通信(简单聊天程序的实现)

利用命名管道实现进程间的通信(简单聊天程序的实现)

管道的本质是一种文件,通常是指把一个进程的输出直接传递给另一个进程的输入。

命名管道(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->cl111     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 }

效果如图:

技术分享           技术分享

利用命名管道实现进程间的通信(简单聊天程序的实现)