FIFO 在使用中存在问题,因为读取器和写入器都必须打开它 - 如果其中一个迟到,另一个就会被阻塞在操作系统内。
我必须实现一个发布机制 - 一个程序发布其日志,如果有人“关心”监听,即打开发布通道,他就会收到消息。如果没有人“关心”,消息就会消失,没问题。支持不超过一个监听器——也没有问题。我可以用什么?
答案1
您可以广播 UDP。这是发件人部分,将任何内容通过管道传递给它:
socat - UDP-DATAGRAM:127.255.255.255:50011,sourceport=50022,broadcast
接收器使用此功能,他们可以随时加入或离开派对:
socat - UDP-LISTEN:50011,bind=127.255.255.255,sourceport=50022,reuseaddr
注释和解释:
- UDP 不保证数据包按顺序到达(请参阅这)
50011
和50022
是您选择的端口号。- 该地址
127.255.255.255
表示发送者通过环回接口进行广播,如果您愿意,可以将其调整为在 LAN 中广播。 - 同样,
bind=127.255.255.255
应该将接收者限制到此接口,这样您就不必担心来自其他地方的(流氓?)UDP 数据包(如果有)。 - 固定
sourceport
有两个原因:- 接收者不会“看到”另一个(恶意?)发送者从另一个(可能是随机的)源端口广播到相同的地址和端口;
- 发送方由于某种原因终止后,您可以重新启动它,所有现有的接收方都不会看到差异;如果发送方使用随机源端口,则现有接收方通常不会“看到”新发送方,因为它们将保持固定在旧源端口上。
reuseaddr
允许多个接收器共存。- 从技术上讲,您可以添加
reuseaddr
到发送方部分,这允许您运行多个发送方。这可能会导致接收端出现交错输出,不推荐。 - 正在运行的发件人将阻止另一个(流氓?)发件人使用完全相同的地址和端口元组。然而,一旦您的发件人被终止,另一个发件人就可以取代它。如果您有 root 访问权限,则可以选择
sourceport
低于1024
.大多数操作系统不会让普通用户绑定到这些端口(名称为“特权端口”);这样,即使发件人已死亡,用户也无法冒充您的发件人。然而,由普通用户运行的接收器可以使用特权端口作为其sourceport
.为了确保只有 root 可以接收,请将另一个端口(50011
在我的示例中)更改为特权端口。