qfedu-linux-advanced-level/day4/chat_tool/chat_tool.c

131 lines
3.4 KiB
C
Raw Permalink Normal View History

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
// 创建FIFO
int createFifo(const char *fifoName)
{
if (mkfifo(fifoName, 0644) == -1) // 创建FIFO
{
if (errno != EEXIST)
{
perror(fifoName); // 输出错误信息
return 1;
}
}
return 0;
}
// 发送数据
void sendData(const char *fifoName, const char *sender)
{
int fd = open(fifoName, O_WRONLY); // 打开FIFO以进行写操作
while (1)
{
char buf[128] = {};
int len = read(STDIN_FILENO, buf, 128); // 从标准输入读取数据
buf[len - 1] = '\0'; // 去除换行符
write(fd, buf, len); // 写入FIFO
if (strcmp(buf, "bye") == 0) // 如果输入为"bye",则退出循环
{
break;
}
}
close(fd); // 关闭FIFO
printf("%s 发送完毕\n", sender); // 输出发送方的信息
}
// 接收数据
void receiveData(const char *fifoName, const char *receiver)
{
int fd = open(fifoName, O_RDONLY); // 打开FIFO以进行读操作
while (1)
{
char buf[128] = "";
int len = read(fd, buf, 128); // 从FIFO读取数据
if (len <= 0)
break;
printf("接收 %s: %s\n", receiver, buf); // 输出接收到的数据和接收方的信息
}
close(fd); // 关闭FIFO
printf("%s 接收完毕\n", receiver); // 输出接收方的信息
}
int main(int argc, char const *argv[])
{
const char *fifo_bob_to_lucy = "fifo_bob_to_lucy"; // Bob到Lucy的FIFO名称
const char *fifo_lucy_to_bob = "fifo_lucy_to_bob"; // Lucy到Bob的FIFO名称
// 创建FIFO
if (createFifo(fifo_bob_to_lucy) != 0) // 创建Bob到Lucy的FIFO
return 1;
if (createFifo(fifo_lucy_to_bob) != 0) // 创建Lucy到Bob的FIFO
return 1;
if (argc != 2)
{
printf("Useage: ./chat_tool [角色名: lucy | bob]");
return 1;
}
if (strcmp(argv[1], "lucy") != 0 && strcmp(argv[1], "bob") != 0)
{
printf("用户仅可选择 lucy 或 bob");
return 1;
}
int i = 0;
for (; i < 2; i++)
{
int pid = fork(); // 创建子进程
if (pid == 0)
break;
}
if (i == 0)
{
// 第一个子进程
if (strcmp(argv[1], "lucy") == 0) // 如果是Lucy方
{
sendData(fifo_lucy_to_bob, "Lucy"); // 发送数据给Bob
}
else if (strcmp(argv[1], "bob") == 0) // 如果是Bob方
{
sendData(fifo_bob_to_lucy, "Bob"); // 发送数据给Lucy
}
}
else if (i == 1)
{
// 第二个进程,读数据
if (strcmp(argv[1], "lucy") == 0) // 如果是Lucy方
{
receiveData(fifo_bob_to_lucy, "Lucy"); // 接收来自Bob的数据
}
else if (strcmp(argv[1], "bob") == 0) // 如果是Bob方
{
receiveData(fifo_lucy_to_bob, "Bob"); // 接收来自Lucy的数据
}
}
else
{
// 主进程
while (1)
{
int pid_ = waitpid(0, NULL, WNOHANG); // 等待所有子进程退出
if (pid_ == -1)
{
// 所有子进程都已经退出
break;
}
}
}
return 0;
}