多播在 golang 中的 Linux 上不起作用
php小编新一,今天要和大家讨论的是在golang中多播在Linux上不起作用的问题。多播是一种网络通信方式,可以在一个发送者和多个接收者之间传输数据。然而,在golang中,我们可能会遇到在Linux操作系统上多播不起作用的情况。本文将解释为什么会出现这个问题,并提供可能的解决方案。让我们开始吧!
问题内容
此代码发送和接收多播包。
此代码适用于 windows 10,但不适用于 linux:为什么?
已发送打包内容(ip 230.0.0.1,目标端口 9001),但应用程序未接收多播
数据包(ip 230.0.0.2,目标端口 9002)。
问题是什么?
为了测试我的应用程序,我使用了 linux vm:也许,这就是原因?
package main import ( "net" "os" "strconv" "time" "github.com/rs/zerolog" "golang.org/x/net/ipv4" ) const device1_tx_multicastAddr = "230.0.0.1" const device1_tx_udp_port = 9001 const device2_tx_multicastAddr = "230.0.0.2" const device2_tx_udp_port = 9002 const packetTxDelayMs = 1000 // const ethName = "Ethernet" // Windows const ethName = "eth0" // Linux const modeDevice2 = false // Device 1 //const modeDevice2 = true // Device 2 var logConsole zerolog.Logger func main() { logConsole = zerolog.New(os.Stderr).With().Timestamp(). Str("module", "main"). Logger().Output(zerolog.ConsoleWriter{Out: os.Stderr}). Level(zerolog.InfoLevel) // ********************************** // Initialize Tx localInterface := getInterfaceByName(ethName) logConsole.Info().Str("func", "main").Msg("localInterface: " + ethName) tx_multicastAddr := device1_tx_multicastAddr rx_multicastAddr := device2_tx_multicastAddr tx_udp_port := device1_tx_udp_port rx_udp_port := device2_tx_udp_port if modeDevice2 { tx_multicastAddr = device2_tx_multicastAddr rx_multicastAddr = device1_tx_multicastAddr tx_udp_port = device2_tx_udp_port rx_udp_port = device1_tx_udp_port } logConsole.Info().Str("func", "main").Msg("Open Tx UDP port " + tx_multicastAddr + ":" + strconv.Itoa(tx_udp_port) + "...") remoteDeviceUdpAddr, err := net.ResolveUDPAddr("udp4", tx_multicastAddr+":"+strconv.Itoa(tx_udp_port)) if err != nil { panic(err) } localDeviceUdpAddr, err2 := net.ResolveUDPAddr("udp4", localInterface.String()+":"+strconv.Itoa(rx_udp_port)) if err2 != nil { panic(err2) } logConsole.Info().Str("func", "main").Msg("Listen UDP: " + localDeviceUdpAddr.String() + "...") localDevice, err2 := net.ListenUDP("udp4", localDeviceUdpAddr) if err2 != nil { panic(err2) } // ********************************** // Initialize Rx udpReceiver := ipv4.NewPacketConn(localDevice) ief, errInterface := net.InterfaceByName(ethName) if errInterface != nil { localDevice.Close() panic(errInterface) } logConsole.Info().Str("func", "main").Msg("Join Multicast: " + rx_multicastAddr + "...") err = udpReceiver.JoinGroup(ief, &net.UDPAddr{IP: net.ParseIP(rx_multicastAddr)}) if err != nil { localDevice.Close() panic(err) } // ********************************** // Run Rx/Tx tasks go sendData(localDevice, remoteDeviceUdpAddr, packetTxDelayMs) receivedData(udpReceiver) } // ************************************************* func sendData(localDevice *net.UDPConn, remoteDeviceUdpAddr *net.UDPAddr, packetDelay uint) { data := []byte("1234567890") for { //logConsole.Info().Str("func", "sendData").Msg("Send...") _, err := localDevice.WriteTo(data, remoteDeviceUdpAddr) if err != nil { panic(err) } time.Sleep(time.Duration(packetDelay) * time.Millisecond) } } func receivedData(receiver *ipv4.PacketConn) { buf := make([]byte, 1500) for { n, _, _, err := receiver.ReadFrom(buf) if err == nil { logConsole.Info().Str("func", "receivedData").Msg("Receive Data: " + string(buf[0:n])) } } } // ************************************************* func getInterfaceByName(name string) net.IP { ief, err := net.InterfaceByName(name) if err != nil { panic(err) } addrs, err := ief.Addrs() if err != nil { panic(err) } var ipAddr net.IP for _, addr := range addrs { ipAddr = addr.(*net.IPNet).IP.To4() if ipAddr != nil { break } } if ipAddr == nil { panic("ipAddr is nil") } return ipAddr }
解决方法
修改应用程序以侦听以下 ip 地址之一将使其在 linux 和 macos 上运行:
- 多播组的ip地址(问题中的
rx_multicastaddr
) - 通配符地址 (
0.0.0.0
)。
但尚不清楚当它侦听 nic 的 ip 地址(例如 192.168.0.5
)时是否可以工作。根据我的测试和问题中的描述,它可以在 windows 上运行,但不能在 linux 或 macos 上运行。我还找不到描述这种行为的权威来源。
下面是一个接受标志的简化演示。
在设备 1 上,使用以下命令运行它(将接口名称替换为您的设备的名称):
go run . -listen 230.0.0.1:9001 -join 230.0.0.1:9001 -send 230.0.0.2:9002 -ifname eth0
在设备 2 上,使用以下命令运行它(将接口名称替换为您设备的接口名称):
go run . -listen 0.0.0.0:9002 -join 230.0.0.2:9002 -send 230.0.0.1:9001 -ifname ethernet
package main import ( "flag" "log" "net" "time" "golang.org/x/net/ipv4" ) var ( listen string join string send string ifname string ) func main() { flag.StringVar(&listen, "listen", "230.0.0.1:9001", "") flag.StringVar(&join, "join", "230.0.0.1:9001", "the multicast group address to receive data from") flag.StringVar(&send, "send", "230.0.0.2:9002", "the multicast group address to send data to") flag.StringVar(&ifname, "ifname", "eth0", "the name of the interface") flag.Parse() itf, err := net.InterfaceByName(ifname) if err != nil { panic(err) } groupAddr, err := net.ResolveUDPAddr("udp4", join) if err != nil { panic(err) } c, err := net.ListenPacket("udp4", listen) if err != nil { panic(err) } defer c.Close() p := ipv4.NewPacketConn(c) if err := p.JoinGroup(itf, &net.UDPAddr{IP: groupAddr.IP}); err != nil { panic(err) } log.Printf("join multicast group %s, waiting...", join) go sendData(c, send) receivedData(p) } func sendData(c net.PacketConn, target string) { data := []byte(ifname) addr, err := net.ResolveUDPAddr("udp4", target) if err != nil { panic(err) } for { _, err := c.WriteTo(data, addr) if err != nil { panic(err) } time.Sleep(time.Second) } } func receivedData(receiver *ipv4.PacketConn) { buf := make([]byte, 1500) for { n, _, _, err := receiver.ReadFrom(buf) if err == nil { log.Printf("Receive Data from: %s\n", buf[0:n]) } } }
以上是多播在 golang 中的 Linux 上不起作用的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

本研究全面深入剖析了在KaliLinux的渗透测试和安全审计流程中可能出现的软件卸载难题,为保障系统稳定可靠贡献了解决之道。一、了解软件的安装方式在进行应用程序卸载前kalilinux卸载软件,首先确定其安装路径是至关重要的步骤。进而,根据所选途径相应地挑选出适当的卸载方案。常见的安装方法包括apt-get、dpkg以及源代码编译等各类形式。每种策略都具备自身特性和相应的卸载措施。二、使用apt-get命令卸载软件在KaliLinux系统中,apt-get功能组件被广泛应用于高效便捷地执行软件包

近日,国产操作系统麒麟Linux广受瞩目,本人身为资深计算机工程师麒麟linux安装教程,对科技创新抱有浓厚兴趣,故亲身体验了该系统的安装流程,现将经验在此和诸位共享。在执行安装程序前,我针对相关步骤进行了充分准备。首要任务是下载并拷贝最新的麒麟Linux操作系统镜像至U盘;其次64位linux,确保已备份个人设备中的重要数据,以应对潜在的安装问题;最后,关闭电脑并插入U盘。进入安装界面重启计算机后,及时按下F12功能键,步入系统启动菜单选择USB优先启动项。随着一个美观且简约的启动画面出现眼前

实际上,电脑使用了较长的一段时间之后,整体的性能都会呈现下降的趋势,而对Windows系统的适应性也会不断地下降。除了电脑本身的原因,Windows系统不断增强和扩展,对硬件要求也越来越高。因此,旧电脑安装Windows系统后出现卡顿现象并不奇怪。之前,很多朋友都在后台询问系统卡顿,旧电脑怎么办?如果你发现将新版Windows10系统安装在旧电脑上会导致卡顿和操作问题,或许考虑转向Linux系统是个不错的选择。大白菜整理了5个微型Linux系统,适合老旧电脑使用,可以有效降低CPU占用率,让你的

Linuxext2文件系统是一种在大部分Linux操作系统上使用的文件系统,它采用了一种高效的磁盘存储结构来管理文件和目录的存储。在深入探讨Linuxext2文件系统的物理存储结构之前,我们首先需要了解一些基本概念。在ext2文件系统中,数据存储在数据块(block)中,数据块是文件系统中最小的可分配单位。每个数据块有固定的大小,通常为1KB、2KB或4

如果您使用Linux操作系统,并希望系统在启动时自动加载驱动器,可以通过将设备的唯一标识符(UID)和挂载点路径添加到fstab配置文件中来实现。fstab是一个位于/etc目录中的文件系统表文件,它包含了系统在启动时需要挂载的文件系统的信息。通过编辑fstab文件,您可以确保在每次系统启动时都能正确加载所需的驱动器,从而保证系统的稳定运行。自动安装驱动器可方便地应用于多种情境。比如,我计划将系统备份到外部存储设备。为了实现自动化,需确保设备与系统保持连接,甚至在启动时。同样,很多应用程序会直接

解决Linux命令行显示乱码问题的方法在Linux操作系统中,有时候我们在使用命令行界面时会遇到显示乱码的情况,这会影响我们对命令输出结果或文件内容的正常查看和理解。造成乱码的原因可能是由于系统字符集设置不正确、终端软件不支持显示特定字符集、文件编码格式不统一等问题。本文将介绍一些解决Linux命令行显示乱码问题的方法,同时提供具体的代码示例,帮助读者解决类

身为2024年的一位Linux热衷者,我对最佳Linux发行版的期待令人兴奋不已。以下,我将阐述个人观点并解析为何2024年最具魅力的Linux发行版具有独特的诸多优点。1.初识Linux最美发行版毫无疑问,2024年的Linux最优发行版堪称科技与艺术的完美融合。其在用户界面、功能规划以及性能优化等多方面表现卓越,使得面对众多竞争对手也能独树一帜。这不仅是一款操作系统,更象征着自由、开放与创新的生活态度。此最优版本融入了全新设计与互动模式,势必令人耳目一新。无论是布局结构、标识图案或色彩搭配,

为什么Linux中的进程会处于休眠状态?在Linux操作系统中,进程可能会处于休眠状态,这是由于多种不同的原因和条件造成的。进程处于休眠状态时,表示该进程暂时被挂起,无法继续执行,直到满足某种条件后才能被唤醒继续执行。接下来将详细介绍在Linux中进程进入休眠状态的几种常见情况,并通过具体的代码示例加以说明。等待I/O完成:当进程发起一个I/O操作(例如读取
