diff --git a/day4/chat_tool/chat_tool b/day4/chat_tool/chat_tool new file mode 100755 index 0000000..11d962b Binary files /dev/null and b/day4/chat_tool/chat_tool differ diff --git a/day4/chat_tool/chat_tool.c b/day4/chat_tool/chat_tool.c new file mode 100644 index 0000000..950bd50 --- /dev/null +++ b/day4/chat_tool/chat_tool.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +// 创建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; +} diff --git a/day4/chat_tool/readme.md b/day4/chat_tool/readme.md new file mode 100644 index 0000000..89372d0 --- /dev/null +++ b/day4/chat_tool/readme.md @@ -0,0 +1,53 @@ +使用文档:chat_tool.c + +该程序是一个聊天工具,允许两个角色("lucy" 和 "bob")之间进行消息的发送和接收。 + +用法: +./chat_tool [角色名: lucy | bob] + +参数说明: + +- 角色名:指定聊天的角色,可选的值为 "lucy" 或 "bob"。 + +注意事项: + +- 在运行程序之前,请确保已经创建了相应的 FIFO(命名管道)。 +- 创建 FIFO 的函数为 `createFifo(const char *fifoName)`,请确保正确调用该函数。 +- FIFO 的名称分别为 "fifo_bob_to_lucy" 和 "fifo_lucy_to_bob"。 + +示例用法: + +1. 创建 FIFO: + $ ./chat_tool bob + $ ./chat_tool lucy + +2. 运行程序: + + - Bob 方发送消息给 Lucy 方: + $ ./chat_tool bob + + - Lucy 方发送消息给 Bob 方: + $ ./chat_tool lucy + +3. 聊天操作: + - 在程序运行后,输入消息并按下回车键发送。 + - 输入 "bye" 退出聊天。 + +注意事项: + +- 请确保在两个不同的终端窗口或会话中分别运行 Bob 方和 Lucy 方。 +- Bob 方和 Lucy 方可以同时发送和接收消息。 + +示例: + +- Bob 方发送消息给 Lucy 方: + $ ./chat_tool bob + Hello Lucy! + How are you? + bye + +- Lucy 方发送消息给 Bob 方: + $ ./chat_tool lucy + Hi Bob! + I'm good. How about you? + bye