在使用有名管道前需要注意有名管道的一些特性。
有名管道(FIFO)的特性:
1.当从管道文件中读取数据后,该数据也会从文件中消失;
2.有名管道可用于非血缘关系的进程中;
3.有名管道是存在文件描述符的,也确确实实在磁盘(闪存)中生成文件;
4.打开有名管道文件时,使用可读可写权限打开,如果只使用可读或可写打开文件,会出现一些特殊清空。
5.有名管道的文件路径不能存在于共享路径中;
6.有名管道具有原子性;等。
群聊室的相关代码
//聊天室
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
//管道文件不能存放在共享路径中
#define FIOF_PATH_GROUP "/tmp/fifo_file_group"
//缓冲区的大小
#define BUFFER_LEN 50
int main()
{
//判断管道文件是否存在
if(access(FIOF_PATH_GROUP,F_OK) != 0)//文件不存在
{
umask(0000);//修改权限掩码为0000,也可以不用该,但得确保管道文件的权限
int mkfifo_ret = mkfifo(FIOF_PATH_GROUP,0777);//创建管道文件,
if(mkfifo_ret != 0)
{
perror("mkfifo");
exit(-1);
}
}
int fd = open(FIOF_PATH_GROUP,O_RDWR);//打开管道文件
if(fd == -1)
{
perror("open");
return -1;
}
char buffer[BUFFER_LEN] = {0};
while(1)
{
bzero(buffer,BUFFER_LEN);//清空缓冲区
read(fd,buffer,BUFFER_LEN);//读取管道文件中的数据
printf("%s\n",buffer);
}
close(fd);//关闭文件
return 0;
}
//聊天个人代码---每个人的代码都一样,只需要修改一下名字或者修改一下,在进入时使用scanf来获取名字
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
//管道文件不能存放在共享路径中
#define FIOF_PATH_GROUP "/tmp/fifo_file_group"
#define USER_NAME "小明"
#define BUFFER_LEN 50
int fd;
//信号响应函数
void func(int signal)
{
char buffer[25];
sprintf(buffer,"%s%s",USER_NAME,"退出群聊!");
write(fd,buffer,25);
exit(-1);
}
int main()
{
signal(SIGINT,func);//捕获CTR C信号
if(access(FIOF_PATH_GROUP,F_OK) != 0)//文件不存在
{
printf("聊天室未打开!\n");
exit(-1);
}
fd = open(FIOF_PATH_GROUP,O_RDWR);//打开文件
if(fd == -1)
{
perror("open");
exit(-1);
}
char MSG[BUFFER_LEN] = {0};
char buffer[BUFFER_LEN] = {0};
sprintf(buffer,"%s%s",USER_NAME,"进入群聊!");
write(fd,buffer,strlen(buffer));
while(1)
{
bzero(buffer,BUFFER_LEN);
scanf("%s",buffer);
sprintf(MSG,"%s:%s",USER_NAME,buffer);
write(fd,MSG,strlen(MSG));
}
close(fd);
exit(0);
}
效果: