go - 组播环回

标签 go networking multicast

我需要在Go上编写多播侦听器。读取数据包时,我会遇到缠绕数据包的问题。看来我需要将IP_MULTICAST_LOOP设置为false。在Go中做起来并不容易。

我找到了this post。似乎应该起作用。但是我仍然可以得到同一主机的副本。应该怎么做?

ipAddr, err := net.ResolveUDPAddr("udp", groupAddress)
if err != nil {...}

iface, err := net.InterfaceByName("en0")
if err != nil {...}

conn, err := net.ListenPacket("udp4", groupAddress)
if err != nil {...}

pc := ipv4.NewPacketConn(conn)

if err := pc.JoinGroup(iface, ipAddr); err != nil {...}

if err := pc.SetMulticastLoopback(false); err != nil {...}


if loop, err := pc.MulticastLoopback(); err == nil {...}

buf := make([]byte, 1024)
for {

    n, _, addr, err := pc.ReadFrom(buf)
    if err != nil {...}

    fmt.Printf("recv from %v: [%s] \n", addr, buf[:n])
}

最佳答案

最简单的方法是在net包中使用ListenMulticastUDP包装器,正如您所指向的另一个SO答案How to set IP_MULTICAST_LOOP on multicast UDPConn in Golang中已经实际解释的那样。

如果您遵循ListenMulticastUDP()的实现,您会在某个时候看到它调用setIPv4MulticastLoopback(fd, false)

如果您需要更高级的内容,ListenMulticastUDP()的文档建议您查看https://godoc.org/golang.org/x/net/ipv4https://godoc.org/golang.org/x/net/ipv6,它们广泛地介绍了如何在Go中进行多播。

这是一些最小的代码(已在MacOS上测试,但与平台无关),显示了如何使用ListenMulticastUDP():

func main() {
    // MDNS (https://en.wikipedia.org/wiki/Multicast_DNS)
    groupAddress := "224.0.0.251:5353"
    ifaceName := "en0"
    if err := run(groupAddress, ifaceName); err != nil {
        fmt.Fprintln(os.Stderr, "error:", err)
        os.Exit(1)
    }
}

func run(groupAddr string, ifaceName string) error {
    iface, err := net.InterfaceByName(ifaceName)
    if err != nil {
        return err
    }

    gaddr, err := net.ResolveUDPAddr("udp", groupAddr)
    if err != nil {
        return err
    }

    conn, err := net.ListenMulticastUDP("udp", iface, gaddr)
    if err != nil {
        return err
    }

    buf := make([]byte, 1024)
    for {
        n, addr, err := conn.ReadFromUDP(buf)
        if err != nil {
            return err
        }
        fmt.Printf("recv %4d bytes from %v\n", n, addr)
    }
}

关于go - 组播环回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60511631/

相关文章:

mysql - 从非sql查询获取结果集

docker - 无法在 docker/bin/sh : <program>: not found 中运行 go 程序

go - 作业中的 {} 是什么?

c - 为什么 IP_TTL 和 IP_MULTICAST_TTL 是独立的套接字选项?

python - 使用Python订阅UDP多播

c++ - 丢包只发生在第一次运行

json - 如何在通用函数中解码 json

networking - GKE:IP地址

javascript - Express 应用程序不响应外部流量

linux - 连接到你自己(并占用一个端口号)