猿问

在Golang中,如何接收绑定到特定地址/端口的套接字的多播数据包?

手头的任务是将套接字专门绑定到地址 1.0.0.2:520(分配给 eth2),然后读取地址为 224.0.0.9:520 的多播 UDP 数据包。


我正在尝试下面的代码,基于https://godoc.org/golang.org/x/net/ipv4


不幸的是,结果是这个调试消息永远不会到达: log.Printf("udpReader: recv %d bytes from %s to %s on %s", n, cm.Src, cm.Dst, ifname)


我知道 eth2 正在接收所需的数据包,因为我在其上运行了此数据包嗅探器:


sudo tcpdump -n -i eth2

18:40:28.571456 IP 1.0.0.1.520 > 224.0.0.9.520: RIPv2, Request, length: 24

18:40:29.556503 IP 1.0.0.1.520 > 224.0.0.9.520: RIPv2, Response, length: 64

这是示例代码。你能发现它为什么不起作用吗?


package main


import (

    "fmt"

    "log"

    "net"


    "golang.org/x/net/ipv4"

)


func main() {

    if err := interfaceAdd("eth2"); err != nil {

        log.Printf("main: error: %v", err)

    }


    log.Printf("main: waiting forever")

    <-make(chan int)

}


func interfaceAdd(s string) error {


    iface, err1 := net.InterfaceByName(s)

    if err1 != nil {

        return err1

    }


    addrList, err2 := iface.Addrs()

    if err2 != nil {

        return err2

    }


    for _, a := range addrList {

        addr, _, err3 := net.ParseCIDR(a.String())

        if err3 != nil {

            log.Printf("interfaceAdd: parse CIDR error for '%s' on '%s': %v", addr, s, err3)

            continue

        }

        if err := join(iface, addr); err != nil {

            log.Printf("interfaceAdd: join error for '%s' on '%s': %v", addr, s, err)

        }

    }


    return nil

}


func join(iface *net.Interface, addr net.IP) error {

    proto := "udp"

    var a string

    if addr.To4() == nil {

        // IPv6

        a = fmt.Sprintf("[%s]", addr.String())

    } else {

        // IPv4

        a = addr.String()

    }


    hostPort := fmt.Sprintf("%s:520", a) // rip multicast port


    // open socket (connection)

    conn, err2 := net.ListenPacket(proto, hostPort)

    if err2 != nil {

        return fmt.Errorf("join: %s/%s listen error: %v", proto, hostPort, err2)

    }


慕容森
浏览 338回答 1
1回答

HUWWW

为了创建多个特定于接口的套接字来接收寻址到相同多播地址 (224.0.0.9:520) 的数据包,我的原始 Go 代码缺少三个主要问题:为了将多个套接字绑定到同一个 UDP 端口,设置 syscall.SO_REUSEADDR为了限制套接字到特定接口,设置 syscall.SO_BINDTODEVICE将 UDP 套接字绑定到 0.0.0.0:520在这里找到完整的示例代码:http&nbsp;:&nbsp;//play.golang.org/p/NprsZPHQmj
随时随地看视频慕课网APP

相关分类

Go
我要回答