Golang中ListenMulticastUDP无法使用255.255.255.255的问题

Golang中ListenMulticastUDP无法使用255.255.255.255的问题 尝试编写一些代码来监听发送到255.255.255.255的UDP广播。

我可以用C语言实现等效代码,但在Go中却无法正常工作。

lAddr, err := net.ResolveUDPAddr("udp", "255.255.255.255:48899")
if err != nil {
    log.Fatal(err)
}

_, err = net.ListenMulticastUDP("udp", nil, lAddr)
if err != nil {
    log.Fatal(err)
}

失败信息: listen udp 255.255.255.255:48899: bind: cannot assign requested address


更多关于Golang中ListenMulticastUDP无法使用255.255.255.255的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

因为看起来 255.255.255.255 在 Go 中似乎不是多播地址:https://play.golang.org/p/l0I-Gbd_edx

维基百科也未将其列为多播地址:https://en.wikipedia.org/wiki/Multicast_address

或许可以尝试在零网络中直接监听该 IP 地址?

func main() {
    fmt.Println("hello world")
}

更多关于Golang中ListenMulticastUDP无法使用255.255.255.255的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的,这是用户操作错误。

255.255.255.255 是广播地址,而不是多播地址。广播 ≠ 多播 😊

广播地址

广播地址

广播地址是一种网络地址,连接到多路访问通信网络的所有设备都能在该地址接收数据报。发送到广播地址的消息可以被所有连接到网络的主机接收。 相比之下,多播地址用于寻址特定的设备组,而单播地址用于寻址单个设备。 在互联网协议版本4(IPv4)网络中,广播地址是主机标识部分的特殊值…

看起来广播数据包会被传递到绑定到该端口的任何套接字。

在Go语言中,net.ListenMulticastUDP 是用于监听多播地址(如 224.0.0.0/4 范围内的地址)的函数,而不是用于广播地址(如 255.255.255.255)。广播地址和多播地址是不同的概念,因此直接使用 255.255.255.255 会导致绑定错误,因为系统不允许绑定到广播地址。

要监听发送到 255.255.255.255 的UDP广播,你应该使用 net.ListenUDP 并绑定到本地地址 0.0.0.0(或特定接口的IP),然后设置套接字选项以允许接收广播数据包。在Go中,你可以通过 net.ListenUDP 结合 syscall.SetsockoptInt 来实现这一点。

以下是一个示例代码,展示如何正确监听UDP广播:

package main

import (
    "log"
    "net"
    "syscall"
)

func main() {
    // 解析本地地址,使用0.0.0.0来绑定所有接口
    lAddr, err := net.ResolveUDPAddr("udp", "0.0.0.0:48899")
    if err != nil {
        log.Fatal(err)
    }

    // 创建UDP连接
    conn, err := net.ListenUDP("udp", lAddr)
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    // 获取文件描述符以设置套接字选项
    file, err := conn.File()
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()

    // 设置SO_BROADCAST选项以允许发送和接收广播
    err = syscall.SetsockoptInt(int(file.Fd()), syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
    if err != nil {
        log.Fatal(err)
    }

    // 现在可以读取广播数据
    buffer := make([]byte, 1024)
    for {
        n, addr, err := conn.ReadFromUDP(buffer)
        if err != nil {
            log.Printf("Error reading from UDP: %v", err)
            continue
        }
        log.Printf("Received broadcast from %s: %s", addr, string(buffer[:n]))
    }
}

在这个示例中:

  • 我们使用 net.ListenUDP 绑定到 0.0.0.0:48899,这允许监听所有接口上的指定端口。
  • 通过 syscall.SetsockoptInt 设置 SO_BROADCAST 选项,确保套接字可以处理广播数据包。
  • 然后使用 ReadFromUDP 循环读取传入的广播数据。

注意:SO_BROADCAST 选项通常用于允许发送广播数据,但在许多系统上,接收广播数据不需要显式设置(绑定到 0.0.0.0 即可)。如果遇到问题,可以尝试添加此选项。如果代码在特定环境中仍无法工作,可能需要检查防火墙或网络配置。

回到顶部