管道-进程案例: 单机聊天程序
This commit is contained in:
parent
85e2fc451e
commit
dea9717412
Binary file not shown.
|
@ -0,0 +1,130 @@
|
||||||
|
#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;
|
||||||
|
}
|
|
@ -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
|
Loading…
Reference in New Issue