【问题标题】:Are datagram pipes possible in Linux?Linux 中是否可以使用数据报管道?
【发布时间】:2016-11-15 20:20:48
【问题描述】:

我正在尝试为我的 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));

为了清楚起见,我主要关心消息边界,以确保在收到读取和读取信号时收到完整的数据包。

【问题讨论】:

  • Unix 域套接字是可靠的。管道比套接字更可靠是什么意思?
  • 主要是从我看到的阅读和对话中看到的。我认为这与套接字的丢包和缓冲区大小限制有关。
  • 在实际网络上可能会出现这种情况,但在本地计算机上,套接字应该非常可靠。您还考虑过使用共享内存或其他 IPC 解决方案吗?
  • 我做了,但归结为使用管道或套接字进行设计。
  • @davmac - Linux man 7 pipe 说:POSIX.1 说小于 PIPE_BUF 字节的 write(2)s 必须是原子的: 输出数据是作为连续序列写入管道。。重点补充。以下句子阐明了此处“原子”的含义:超过 PIPE_BUF 字节的写入可能是非原子的:内核可能将数据与其他进程写入的数据交错。

标签: c++ linux sockets pipe


【解决方案1】:

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

此外,man page for pipe 表示您可以将O_DIRECT 标志用于“数据包模式”,以确保小于PIPE_BUF 字节的write 被视为数据包和read 操作将检索单个数据包。但是,尚不清楚这是否也适用于命名的 fifo。

但是:

我一直在寻找主要是管道来执行此操作,因为它比套接字更可靠

这是不正确的。 Linux 上的 Unix 数据报套接字是可靠的并保持消息顺序。在这里,它们看起来非常合适。

【讨论】:

    猜你喜欢
    • 2022-07-18
    • 1970-01-01
    • 1970-01-01
    • 2017-01-27
    • 2017-08-17
    • 2020-03-28
    • 1970-01-01
    • 2011-06-11
    • 2020-10-30
    相关资源
    最近更新 更多