V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
dyllen
V2EX  ›  Go 编程语言

广域网 udp 组播如何发送数据?

  •  
  •   dyllen · 132 天前 · 2801 次点击
    这是一个创建于 132 天前的主题,其中的信息可能已经有所发展或是发生改变。

    刚看 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 。

    第 1 条附言  ·  132 天前
    搜了下 udp 组播的文章,都是局域网的,没找到几个公网 ip 之间怎么 udp 组播相关实现文章。
    第 2 条附言  ·  132 天前
    没啥需求,纯粹是在研究 go 里面是怎么写 udp 的。
    第 3 条附言  ·  132 天前
    纯粹研究 go 里面怎么写 udp ,看到 udp 组播标准里面是可以广域网的,然后又没找到怎么广域网的示例代码。
    35 条回复    2024-07-30 09:38:09 +08:00
    tool2dx
        1
    tool2dx  
       132 天前
    组播好像是要发送 IGMP 包,用 IP_ADD_MEMBERSHIP 加入才行。
    b821025551b
        2
    b821025551b  
       132 天前
    组播,需要加组的啊,通过 IGMP 协议进行组内设备管理,你这里当然只管发送就行了。
    kenvix
        3
    kenvix  
       132 天前   ❤️ 1
    你对网络路由的理解有一些问题,组播路由是组播路由,单播路由是单播路由。

    然后答案是不可能,你发不出去。因为广域网没有路由组播地址。
    kenvix
        4
    kenvix  
       132 天前   ❤️ 2
    @kenvix #3 如果一定要组播,必须要用 VPN 承载流量,封装到单播里面。IPV4 广域网只路由了单播地址
    julyclyde
        5
    julyclyde  
       132 天前
    广域网就基本别想了
    IGMP 协议、acl 都没开放的
    cnbatch
        6
    cnbatch  
       132 天前
    想要使用组播,是需要事先在路由器里面做好配置才行的,并不是发送方说了算

    想要在广域网发送组播,意味着需要修改广域网路由器的设置,然而这些路由器是运营商的,普通用户哪能改得了
    pagxir
        7
    pagxir  
       132 天前 via Android
    需要组播路由,需要中间设备支持 igmp snooping. 终端设备发送 IP_ADD_MEMBERSHIP 请求加入主播组,中间设备就会一级级上报创建一条组播路由,当发送的时候路由器根据创建的组播路由表逐个网口进行转发,最后到终端。这就是 IPTV 直播的技术基础
    dyllen
        8
    dyllen  
    OP
       132 天前
    @kenvix
    @cnbatch

    就是说 ucp 组播说是可以广域网,实际基本也就是只能局域网了吗?
    dyllen
        9
    dyllen  
    OP
       132 天前
    @julyclyde
    @cnbatch
    就是说 ucp 组播说是可以广域网,实际基本也就是只能局域网了吗?
    julyclyde
        10
    julyclyde  
       132 天前   ❤️ 1
    @dyllen 技术上并没禁止广域网,但运营商在实际业务中禁止了
    NewYear
        11
    NewYear  
       132 天前
    组播本质上就是在局域网使用的,不会通过路由器转发。因为它是基于“广播包”的特性来实现的。广播包绝不会经过路由器,否则随随便便全网就崩了。。。。如果你的使用场景不是这个,那麻烦你使用 TCP 、UDP 协议(客户端 IP 、服务器 IP)方式使用。。。不要想当然。

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

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

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


    估计这段话你还是看不懂……建议你还是直接使用 TCP 协议吧,UDP 协议是很简单的协议,但是涉及到组播,就要懂一些网络基础才能理解,否则就会满脑子疑惑为什么不按你的想法来。
    julyclyde
        12
    julyclyde  
       132 天前
    @NewYear 我觉得你还是再学习一下吧
    NewYear
        13
    NewYear  
       132 天前
    你可以想象一下,你的路由器上层就是互联网了(虽然物理上还在机房,但逻辑上已经是互联网了),整个互联网的组播包都访问 224.0.0.250 ,你觉得 224.0.0.250 这个 IP 应该属于谁?谁家服务器扛得住?不是瞬间就爆炸了么。

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

    对了,也可以用第三方服务器,比如 MQTT 协议,这种有免费的第三方服务器。
    pagxir
        14
    pagxir  
       132 天前 via Android   ❤️ 1
    @NewYear #11 一段话里面就出了两个错,我也觉得你好好回去看协议。
    NewYear
        15
    NewYear  
       132 天前
    @julyclyde

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

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

    不用回我了,不是技术交流我不会浪费时间回,谢谢。
    NewYear
        16
    NewYear  
       132 天前
    @dyllen

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

    大家可以直接帮你推荐一个协议或者解决方案,以免用错了协议然后在错误的方向一直绕圈,从你的主题看,你应该是用错协议了。
    NewYear
        17
    NewYear  
       132 天前
    仔细想了一下,学组播协议是之前很久了,有的细节忘记了,好像是有些冲突的地方,不好意思了。不过使用场景还记得,看楼主的用法确实不太合适。

    还是从需求的角度考虑用什么吧,要不然大家的回答都是“这样不行”,“那样也不行”,不如重新提一下“需求是什么”,这样大家直接帮你找到答案了。
    skykk1op
        18
    skykk1op  
       132 天前
    运营商的 IPTV 就是采用了组播流量,但网络中需要路由器配置 pim-sm 、igmp 加入组等功能。
    普通用户别想了
    lambdaq
        19
    lambdaq  
       132 天前
    组播这事我事一直有点没搞懂。比如有个终端一直丢包,这个路由器会负责重发吗?还是丢了就丢了。

    如果路由器这点都不管,那组不组有啥区别。。。
    opengps
        20
    opengps  
       132 天前
    如果非局域网开放了广播,那现有的带宽哪够转发 udp 数据的,所以广域网下屏蔽了广播
    lambdaq
        21
    lambdaq  
       132 天前
    @opengps 但承载业务的流量并不会因此变少啊。都改走单播了不是。
    opengps
        22
    opengps  
       132 天前
    @lambdaq 组播是在最后一个网段交换机处分散给多个目标地址吗?如果这样的话就没有我考虑的带宽不够用问题了
    wolongzb
        23
    wolongzb  
       132 天前
    @lambdaq 组播本身承载与 UDP 数据包中,UDP 协议本身是不可靠的,没有确认机制,不会重发。
    kenvix
        24
    kenvix  
       132 天前
    @dyllen #9 是的,裸组播是没办法在广域网路由的,只能封装。可以考虑用 Zerotier 等 VPN 封装一下再合理配置组播路由就可以了
    kenvix
        25
    kenvix  
       132 天前
    @dyllen #9 另外 L2 VPN 可以避免配置 IGMP 和组播路由,L3 VPN 则需要配置
    kenvix
        26
    kenvix  
       132 天前
    @lambdaq #19 你说的东西是 L4 的东西。IP 单播也不管丢包啊。这种问题 L4 去解决,组播有 PGM 协议
    dyllen
        27
    dyllen  
    OP
       132 天前
    @NewYear 你说的我可能会疑惑的地方我并不会疑惑,我只是看到组播理论上可以广域网,实际又没找到相关代码,就问问。
    dyllen
        28
    dyllen  
    OP
       132 天前
    @NewYear 我没啥需求,纯粹是在研究 go 里面是怎么写 udp 的。
    lambdaq
        29
    lambdaq  
       132 天前
    @wolongzb @kenvix 所以组播这种发一堆包可能丢几个,接收方 head of line blocking 了怎么办。。。?感觉这协议用处不大,除非就是语音 视频这种丢几帧无所谓的

    @opengps 我大概明白了。节约了上传者的带宽。。好像有点道理。
    dyllen
        30
    dyllen  
    OP
       132 天前
    @lambdaq udp 本来就是用在对丢包不敏感的场景下的,像语音,丢了就信号不好,叫对方重新说。
    GeekGao
        31
    GeekGao  
       131 天前
    运营商的家庭网线路,没有对一般客户开放组播路由协议(如 PIM 、DVMRP 、MOSPF 等),所以你是播不了的。只能在你自己的局域网里耍。
    tywtyw2002
        32
    tywtyw2002  
       131 天前
    组播?
    你先读一读 TCP/IP 路由技术,然后再去读一读 IP 组播

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

    局域网的话,组播也要配置,交换机要根据组播 mac 地址做剪枝的。不配置的话组播没法进行。
    UN2758
        33
    UN2758  
       131 天前
    @NewYear #11 「组播本质上就是在局域网使用的,不会通过路由器转发。因为它是基于“广播包”的特性来实现的。广播包绝不会经过路由器,否则随随便便全网就崩了」,有点没看懂,组播不通过组播路由表怎么转发???
    pagxir
        34
    pagxir  
       131 天前 via Android
    @UN2758 #33 所以这话里面包含了错误,错误的将网络广播跟链路广播混一起了。虽然两者会有映射关系但并不等同。组播同理
    sztink
        35
    sztink  
       126 天前
    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
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1200 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 18:18 · PVG 02:18 · LAX 10:18 · JFK 13:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.