相关文章推荐
耍酷的西红柿  ·  IHttpClientFactory ...·  3 月前    · 
听话的跑步鞋  ·  【Shell】while ...·  1 年前    · 
帅呆的大熊猫  ·  ScrollBar.OnValueChang ...·  1 年前    · 

数据报管道在Linux中是否可行?

3 人关注

我正试图为我的Linux守护程序编写一些IPC机制,以便与其他进程对话。我一直在考虑主要通过管道来实现这一目标,因为它比套接字更可靠。但现在我有一个问题:数据报连接是否可以通过管道来实现?

目前我正在做这样的事情(为了清楚起见,删除了错误处理)。

mkfifo("path/to/named/pipe1", 0660);
int ret_fd = open("path/to/named/pipe1", O_RDONLY | O_NONBLOCK);

对于插座,我可以做这样的事情。

sockaddr_un sock;
sock.sun_family = AF_UNIX;
sprintf(sock.sun_path, "path/to/named/pipe1");
unlink(sock.sun_path);
int ret_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); //maybe SOCK_SEQPACKET is better/more reliable
bind(ret_fd, (sockaddr*)(&sock), sizeof(sock));

为了显而易见,我主要关注的是消息边界,以确保我在得到阅读信号和阅读时获得完整的数据包。

5 个评论
Unix域套接字是可靠的。你说管道比套接字更可靠是什么意思?
大多数情况下,我只是从阅读和对话中看到这个问题。我认为这与数据包丢弃和套接字的缓冲区大小限制有关。
在实际的网络中可能是这样,但在本地机器上,套接字应该是相当可靠的。另外,你有没有考虑过使用共享内存或其他IPC解决方案?
我做过,但为了设计的目的,最终还是要使用管道或插座。
@davmac - Linux man 7 pipe says: POSIX.1说,小于PIPE_BUF字节的写(2)必须是原子性的。 输出数据作为一个连续的序列被写入管道。 . 着重号是后加的。 下面的句子澄清了 "原子 "在这里的含义。 超过PIPE_BUF字节的写入可能是非原子性的:内核可能将数据与其他进程写入的数据交织在一起。
c++
linux
sockets
pipe
Chef Pharaoh
Chef Pharaoh
发布于 2016-11-16
1 个回答
davmac
davmac
发布于 2016-11-16
已采纳
0 人赞同

正如Brian McFarland的评论所指出的,你可以通过选择一个固定的数据报长度(必须小于 PIPE_BUF )在管道上可靠地传输数据报。所有这个长度的写入都是原子的,而所有这个长度的读取都将从管道的缓冲区中提取一个数据报。

此外,还有 管子的手册页 说你可以使用 O_DIRECT 标志来实现 "数据包模式",确保小于 PIPE_BUF 字节的 write 被视为一个数据包,而 read 操作将检索到一个数据包。然而,目前还不清楚这是否也适用于命名的fifos。

However: