如何使用Golang在互联网上实现组播?

huangapple go评论83阅读模式
英文:

How to use golang to implement multicast over Internet?

问题

我是一个Golang编程和多播编程的新手。我在https://gist.github.com/fiorix/9664255上看到了一个关于Golang多播的程序。

import (
	"encoding/hex"
	"log"
	"net"
	"time"
)

const (
	srvAddr         = "224.0.0.1:9999"
	maxDatagramSize = 8192
)

// 发送多播数据
func ping(a string) {
	addr, err := net.ResolveUDPAddr("udp", a)
	if err != nil {
		log.Fatal(err)
	}
	c, err := net.DialUDP("udp", nil, addr)
	for {
		c.Write([]byte("hello, world\n"))
		time.Sleep(1 * time.Second)
	}
}

// 打印接收到的数据
func msgHandler(src *net.UDPAddr, n int, b []byte) {
	log.Println(n, "bytes read from", src)
	log.Println(hex.Dump(b[:n]))
}

// 加入多播组并接收多播数据
func serveMulticastUDP(a string, h func(*net.UDPAddr, int, []byte)) {
	addr, err := net.ResolveUDPAddr("udp", a)
	if err != nil {
		log.Fatal(err)
	}
	l, err := net.ListenMulticastUDP("udp", nil, addr)
	l.SetReadBuffer(maxDatagramSize)
	for {
		b := make([]byte, maxDatagramSize)
		n, src, err := l.ReadFromUDP(b)
		if err != nil {
			log.Fatal("ReadFromUDP failed:", err)
		}
		h(src, n, b)
	}
}

我在大学实验室的局域网中的几台计算机上运行了这段代码。一台计算机运行ping函数发送多播数据包,其他计算机运行serveMulticastUDP函数接收多播数据包。这样是成功的。

但是当我在一个计算机上运行ping函数发送多播数据包,在另一个不在同一个局域网的计算机上运行serveMulticastUDP函数接收数据包时,它无法接收到数据。接收方有一个NAT,并且没有公共IP地址。

我看到一些人的回答说互联网不支持多播。但是据我所知,VoIP是多播技术的一个例子,我们可以在互联网上实现多播。

那么接收方无法接收数据包的原因是什么?我应该如何修改代码以在互联网上实现多播?

英文:

I'm a new person in golang programming and multicast programming.I saw a program about golang multicast in https://gist.github.com/fiorix/9664255.

import (
	"encoding/hex"
	"log"
	"net"
	"time"
)

const (
	srvAddr         = "224.0.0.1:9999"
	maxDatagramSize = 8192
)

//send multicast data
func ping(a string) {
	addr, err := net.ResolveUDPAddr("udp", a)
	if err != nil {
		log.Fatal(err)
	}
	c, err := net.DialUDP("udp", nil, addr)
	for {
		c.Write([]byte("hello, world\n"))
		time.Sleep(1 * time.Second)
	}
}

//print received data
func msgHandler(src *net.UDPAddr, n int, b []byte) {
	log.Println(n, "bytes read from", src)
	log.Println(hex.Dump(b[:n]))
}

//join multicast group and receive multicast data
func serveMulticastUDP(a string, h func(*net.UDPAddr, int, []byte)) {
	addr, err := net.ResolveUDPAddr("udp", a)
	if err != nil {
		log.Fatal(err)
	}
	l, err := net.ListenMulticastUDP("udp", nil, addr)
	l.SetReadBuffer(maxDatagramSize)
	for {
		b := make([]byte, maxDatagramSize)
		n, src, err := l.ReadFromUDP(b)
		if err != nil {
			log.Fatal("ReadFromUDP failed:", err)
		}
		h(src, n, b)
	}
}

I ran the code on several computers in a University lab LAN.One computer ran function ping to send multicast packets and others ran function serveMulticastUDP to receive the Multicast packets.It seccessed.
But when I ran function ping on one computer and ran function serveMulticastUDP on an other computer in the Internet(two computers are not in a LAN),it could not receive the data.The receiver has a NAT and did not have a public IP address.

I saw some people's answer that Internet don't support multicast.But as I know that VOIP is an example of multicast technology,we can implement multicast in the Internet.

So what's the reason that the receiver couldn't receive packets?What should I do to modify the code to implement multicast over Internet?

答案1

得分: 9

组播路由与单播路由非常不同。组播是一种广播形式,通常不会跨越路由器。您可以启用组播路由,但必须在路径上的所有路由器上启用(使用相同的组播路由类型),而这在公共互联网上是不可能的。公共互联网将因为密集模式组播而崩溃,而且没有任何ISP会将资源用于稀疏模式。

我不确定您为什么认为VoIP使用组播(实际上并不是这样)。

如果您想要在公共互联网上从一个站点组播到另一个站点,那么您必须使用支持组播的隧道,例如GRE。这将在单播数据包中封装您的组播数据包以跨越公共互联网。您仍然必须配置每一侧的路由器以支持组播路由。

英文:

Multicast routing is very different from unicast routing. Multicast is a form of broadcast, and it normally doesn't cross routers. You can enable multicast routing, but it must be enabled (using the same multicast routing type) on all the routers in a path, and that simply cannot happen on the public Internet. The public Internet would collapse from dense mode multicast, and no ISPs are going to dedicate resources to sparse mode.

I'm not sure why you think VoIP uses multicast (it doesn't).

If you want to multicast from one site to another site across the public Internet, then you must use a tunnel that supports multicast, e.g. GRE. This will wrap your multicast packets inside unicast packets to cross the public Internet. You must still configure the routers on each side to support multicast routing.

huangapple
  • 本文由 发表于 2017年9月19日 22:50:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/46303587.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定