Golang Go语言中广域网 udp 组播如何发送数据?

刚看 udp 组播,写了个 demo ,组播地址是 224.0.0.250 ,监听端口是 9985

发送方代码

func stdlibClient() {
	ip := net.ParseIP("224.0.0.250")
	srcAddr := &net.UDPAddr{IP: net.IPv4zero, Port: 0}
	dstAddr := &net.UDPAddr{IP: ip, Port: 9985}
	conn, err := net.DialUDP("udp", srcAddr, dstAddr)
	if err != nil {
		log.Println(err)
	}
	defer conn.Close()
	conn.Write([]byte("hello"))
	log.Printf("stdlibClient <%s>\n", conn.RemoteAddr())
}

我在想 dstAddr 指定的是组播的地址,如果接收方在广域网上,他是如何找到对方的?又没有指定对方的公网 IP 。


Golang Go语言中广域网 udp 组播如何发送数据?

更多关于Golang Go语言中广域网 udp 组播如何发送数据?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

36 回复

组播好像是要发送 IGMP 包,用 IP_ADD_MEMBERSHIP 加入才行。

更多关于Golang Go语言中广域网 udp 组播如何发送数据?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


组播,需要加组的啊,通过 IGMP 协议进行组内设备管理,你这里当然只管发送就行了。

你对网络路由的理解有一些问题,组播路由是组播路由,单播路由是单播路由。

然后答案是不可能,你发不出去。因为广域网没有路由组播地址。

#3 如果一定要组播,必须要用 VPN 承载流量,封装到单播里面。IPV4 广域网只路由了单播地址

广域网就基本别想了
IGMP 协议、acl 都没开放的

想要使用组播,是需要事先在路由器里面做好配置才行的,并不是发送方说了算

想要在广域网发送组播,意味着需要修改广域网路由器的设置,然而这些路由器是运营商的,普通用户哪能改得了

需要组播路由,需要中间设备支持 igmp snooping. 终端设备发送 IP_ADD_MEMBERSHIP 请求加入主播组,中间设备就会一级级上报创建一条组播路由,当发送的时候路由器根据创建的组播路由表逐个网口进行转发,最后到终端。这就是 IPTV 直播的技术基础




就是说 ucp 组播说是可以广域网,实际基本也就是只能局域网了吗?



就是说 ucp 组播说是可以广域网,实际基本也就是只能局域网了吗?

技术上并没禁止广域网,但运营商在实际业务中禁止了

组播本质上就是在局域网使用的,不会通过路由器转发。因为它是基于“广播包”的特性来实现的。广播包绝不会经过路由器,否则随随便便全网就崩了。。。。如果你的使用场景不是这个,那麻烦你使用 TCP 、UDP 协议(客户端 IP 、服务器 IP)方式使用。。。不要想当然。

如果你非要经过路由器,那么麻烦你写个代(敏感词)理,收包的时候转发到互联网,也可以使用一些例如 VP(敏感词)N 、代(敏感词)理、内网穿透等技术,转到对方的局域网。

可能你很难理解,为什么是这样……这解释起来太费劲了,只能说每个协议有每个协议的特性。

另外你可能会问。224 这个网段明明不是局域网 IP ,凭什么不能经过路由器?这是因为操作系统和路由器上面都写死了啊,这个网段它就不可能被转发。(除了少数系统没有遵守这个标准)


估计这段话你还是看不懂……建议你还是直接使用 TCP 协议吧,UDP 协议是很简单的协议,但是涉及到组播,就要懂一些网络基础才能理解,否则就会满脑子疑惑为什么不按你的想法来。

我觉得你还是再学习一下吧

你可以想象一下,你的路由器上层就是互联网了(虽然物理上还在机房,但逻辑上已经是互联网了),整个互联网的组播包都访问 224.0.0.250 ,你觉得 224.0.0.250 这个 IP 应该属于谁?谁家服务器扛得住?不是瞬间就爆炸了么。

哎,解释多了也没用,你研究这个也不会研究出结果。。。。。你试着用 TCP 实现你的需求吧,如果实现不了,就用 VP(敏感词)N 或者内网穿透技术,一定能解决你的问题。如果解决不了,那就是你缺少资源,比如你在互联网上没有服务器,也没有自己的公网 IP ,那就想太多了。。。。

对了,也可以用第三方服务器,比如 MQTT 协议,这种有免费的第三方服务器。

#11 一段话里面就出了两个错,我也觉得你好好回去看协议。



你上来贬低人显得你很懂吗?

我的帖子是回复给楼主的,可能不是那么的牛逼,也只是尽量在解答问题。不是为了和你比拼谁的技术更高。我很乐意从别人的回复中学到一些东西,也很乐意别人指正我写错了什么。但是不是为了和谁吵架。

不用回我了,不是技术交流我不会浪费时间回,谢谢。



楼主,建议你重新描述一下,你实际的需求是什么样的(构思的也可以),什么样的场景,传输的内容是什么类型的(如大小、频率)。

大家可以直接帮你推荐一个协议或者解决方案,以免用错了协议然后在错误的方向一直绕圈,从你的主题看,你应该是用错协议了。

仔细想了一下,学组播协议是之前很久了,有的细节忘记了,好像是有些冲突的地方,不好意思了。不过使用场景还记得,看楼主的用法确实不太合适。

还是从需求的角度考虑用什么吧,要不然大家的回答都是“这样不行”,“那样也不行”,不如重新提一下“需求是什么”,这样大家直接帮你找到答案了。

运营商的 IPTV 就是采用了组播流量,但网络中需要路由器配置 pim-sm 、igmp 加入组等功能。
普通用户别想了

组播这事我事一直有点没搞懂。比如有个终端一直丢包,这个路由器会负责重发吗?还是丢了就丢了。

如果路由器这点都不管,那组不组有啥区别。。。

如果非局域网开放了广播,那现有的带宽哪够转发 udp 数据的,所以广域网下屏蔽了广播

但承载业务的流量并不会因此变少啊。都改走单播了不是。

组播是在最后一个网段交换机处分散给多个目标地址吗?如果这样的话就没有我考虑的带宽不够用问题了

组播本身承载与 UDP 数据包中,UDP 协议本身是不可靠的,没有确认机制,不会重发。

#9 是的,裸组播是没办法在广域网路由的,只能封装。可以考虑用 Zerotier 等 VPN 封装一下再合理配置组播路由就可以了

#9 另外 L2 VPN 可以避免配置 IGMP 和组播路由,L3 VPN 则需要配置

#19 你说的东西是 L4 的东西。IP 单播也不管丢包啊。这种问题 L4 去解决,组播有 PGM 协议

你说的我可能会疑惑的地方我并不会疑惑,我只是看到组播理论上可以广域网,实际又没找到相关代码,就问问。

我没啥需求,纯粹是在研究 go 里面是怎么写 udp 的。

所以组播这种发一堆包可能丢几个,接收方 head of line blocking 了怎么办。。。?感觉这协议用处不大,除非就是语音 视频这种丢几帧无所谓的

我大概明白了。节约了上传者的带宽。。好像有点道理。

udp 本来就是用在对丢包不敏感的场景下的,像语音,丢了就信号不好,叫对方重新说。

运营商的家庭网线路,没有对一般客户开放组播路由协议(如 PIM 、DVMRP 、MOSPF 等),所以你是播不了的。只能在你自己的局域网里耍。

组播?
你先读一读 TCP/IP 路由技术,然后再去读一读 IP 组播

公网?业务上级路由器交换机都不配置组播,你组播包,进去就直接丢弃处理。

局域网的话,组播也要配置,交换机要根据组播 mac 地址做剪枝的。不配置的话组播没法进行。

#11 「组播本质上就是在局域网使用的,不会通过路由器转发。因为它是基于“广播包”的特性来实现的。广播包绝不会经过路由器,否则随随便便全网就崩了」,有点没看懂,组播不通过组播路由表怎么转发???

#33 所以这话里面包含了错误,错误的将网络广播跟链路广播混一起了。虽然两者会有映射关系但并不等同。组播同理

  1. 发送方不需要加入多播(也叫组播)组,可以直接发送消息
    2. 接收方需要加入多播组中,才能接收到消息。多播是支持广域网的,现实中限制条件太多,更多的用在局域网。

    欲了解详细的基础知识可以看《 UNIX 网络编程 卷 1:套接字联网 API 》一书。这里有这本书的笔记: https://note.cyub.vip/unp-v1/

    Go 语言可以参考 ssdp 协议的 go 实现: https://github.com/koron/go-ssdp/blob/main/internal/multicast/multicast.go#L68-L91

在Go语言中,使用UDP组播(Multicast)发送数据到广域网(WAN)上,需要配置UDP套接字选项以启用组播功能,并将数据发送到特定的组播地址。以下是一个基本示例,展示如何在Go中实现这一点:

  1. 导入必要的包

    package main
    
    import (
        "fmt"
        "net"
        "os"
    )
    
  2. 设置组播地址和端口

    const (
        multicastAddr = "239.255.255.250:12345" // 示例组播地址和端口
    )
    
  3. 创建UDP连接并配置组播

    func main() {
        addr, err := net.ResolveUDPAddr("udp4", multicastAddr)
        if err != nil {
            fmt.Println("Error resolving address:", err)
            os.Exit(1)
        }
    
        conn, err := net.DialUDP("udp4", nil, addr)
        if err != nil {
            fmt.Println("Error dialing:", err)
            os.Exit(1)
        }
        defer conn.Close()
    
        // 发送数据
        message := []byte("Hello, Multicast!")
        _, err = conn.Write(message)
        if err != nil {
            fmt.Println("Error writing:", err)
        } else {
            fmt.Println("Message sent successfully")
        }
    }
    

注意:

  • 组播地址通常位于224.0.0.0到239.255.255.255之间。
  • 在广域网上使用组播时,可能需要配置路由器和防火墙以允许组播流量。
  • 本示例使用IPv4(udp4),IPv6类似,但需调整地址和协议类型。

希望这个示例能帮助你在Go语言中实现UDP组播发送数据。

回到顶部