/**********************************************************************************
命名管道 (FIFO)
利用命名管道实现单机双人聊天
提示: 父进程创建子进程,实现多任务。父进程负责发信息(向FIFO里写数据),子进
程负责接收信息( 从FIFO里读数据)。 打开命名管道的用阻塞的方法打开。
***********************************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
//条件编译
#ifdef LUCY
char sender_name[] = "lucy";
char receiver_name[] = "peter";
#define SEND_FIFO "L_P"
#define RECEIVE_FIFO "P_L"
#endif
#ifdef PETER
char sender_name[] = "peter";
char receiver_name[] = "lucy";
#define SEND_FIFO "P_L"
#define RECEIVE_FIFO "L_P"
#endif
void talk(void)
{
pid_t pid;
//建立两个管道分别实现收发消息
mkfifo(SEND_FIFO, 0666);
mkfifo(RECEIVE_FIFO, 0666);
pid = fork();
if(pid < 0)
{
perror("fork");
}
else if(pid == 0)//接收信息
{
int receive_fd;
//以只读方式打开管道而使管道在无写者时阻塞
receive_fd = open(RECEIVE_FIFO, O_RDONLY);
while(1)
{
char tmp[255] = "";
int ret;
ret = read(receive_fd, tmp, sizeof(tmp));
if(ret == 0)
{
break;
}
printf("\r\e[K%s:%s\n", receiver_name, tmp);
printf("%s:", sender_name);
fflush(stdout);//刷新缓冲区
}
}
else if(pid > 0)//发信息
{
int send_fd;
//以只写方式打开管道而使管道在无读者时阻塞
send_fd = open(SEND_FIFO, O_WRONLY);
while(1)
{
char tmp[255] = "";
printf("%s:", sender_name);
fflush(stdout);
fgets(tmp, sizeof(tmp), stdin);
//fprintf(stdin,"%s",tmp);
tmp[strlen(tmp)-1] = 0;//将fgets得到的\n换成\0
write(send_fd, tmp, strlen(tmp));
}
}
}
int main(int argc, char *argv[])
{
talk();
return 0;
}
编译:
gcc -DLUCY fifo.c -o lucy
gcc -DPETER fifo.c -o peter
使用两个终端运行上面两个应用会生成两个管道文件节点如下: