131 lines
3.4 KiB
C
131 lines
3.4 KiB
C
|
#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;
|
||
|
}
|