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中文網其他相關文章!

Linux的发行版有很多,这里罗列7个漂亮的Linux发行版,可以说是Linux操作系统界的颜值担当了。elementaryOS网站:https://elementaryos.cnelementaryOS操作系统是最漂亮的Linux发行版之一。它基于macOS外观,同时为Linux用户提供了出色的用户体验。如果用户已经习惯使用macOS,则使用elementaryOS不会有任何问题。另外,elementaryOS操作系统基于Ubuntu,因此用户也可以轻松找到大量应用程序来完成任务。elemen

内核空间和用户空间对于32位操作系统而言,它的寻址空间(也称为虚拟地址空间或线性地址空间)大小为4G(即2的32次方)。这意味着一个进程可以拥有最大4G的地址空间。操作系统的核心是内核(kernel),它是与普通应用程序分离的,有权限访问受保护的内存空间和底层硬件设备。为了保证内核的安全,现代操作系统通常限制用户进程直接操作内核。通常,这通过将虚拟地址空间划分为两个部分来实现,即内核空间和用户空间。就Linux操作系统而言,最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF)被

linux系统下svn安装方式常见有3种:1、使用操作系统预编译的软件包工具,如在“Ubuntu/Debian”上使用“sudo apt-get update”“sudo apt-get install subversion”进行安装;2、从源代码编译安装,官网下载源代码然后在Linux终端执行命令进行编译和安装;3、使用第三方包管理器如“Yum”进行安装,注意依赖项问题即可。

一、前言在学习Linux操作系统时,你是否曾经有过这样的疑问:为什么我们的电脑能够识别并使用不同的USB设备呢?为什么Linux系统不会把鼠标当成键盘来使用呢?让我们一起来探讨一下USB设备在Linux系统中的识别和加载过程。二、USB设备的识别和加载当我们将一个USB设备插入电脑时,Linux内核会自动检测并加载相应的驱动程序,使设备能够正常工作。接下来,我们将深入探讨USB设备在Linux系统中的识别和加载过程。2.1USB控制器检测设备插入USB控制器是一个硬件设备,用于控制USB总线上的

在这里为大家介绍一下统信uos安装的配置要求,统信uos是一款基于Linux内核的国产操作系统,具有稳定、安全、易用等特点,因此在国内得到了广泛的应用,为了确保统信uos的顺利安装和运行,我们需要了解它的配置要求。硬件配置统信uos的安装对硬件有一定的要求,具体如下:处理器:x86或x86_64架构的处理器,建议使用主频在1GHz以上的处理器。内存:至少2GB内存,建议使用4GB或以上内存。硬盘:至少20GB可用空间的硬盘,建议使用SSD固态硬盘以提高系统运行速度。显卡:支持DirectX9.0

如果一个系统被多个用户使用,你或许出于个人原因想在文件管理器中隐藏一些文件或文件夹不让其他人看到(绝大多数用户不会对Linux系统进行深入了解,所以他们只会看到文件管理器列出的文件和文件夹),我们有三种方法可以来做这件事。此外,(除了隐藏)你还可以使用密码保护文件或文件夹。在这个教程中,我们将讨论如何用非重命名的方法在文件管理器中隐藏文件和文件夹。我们都知道,通过以点(“.”)前缀重命名一个文件或文件夹的方式,可以在Linux中将该文件或文件夹隐藏。但这不是隐藏文件或文件夹的正确/高效方式。一些

在Unix或Linux操作系统上,scp实用程序(securecopy)与更著名的命令cp类似,但用于在安全加密的网络上在主机之间传输文件和目录。由于它依赖于ssh进行数据传输,因此它提供了相同的安全性并使用了相同的身份验证ssh。与rcp不同,scp命令将提示您输入用于身份验证的密码(如果需要)。在本文中,我们将深入研究Linux中文件的安全传输,并学习如何使用scp命令。通过对常用scp开关和选项的详细解释和示例用例,您将了解如何使用此实用程序。在开始之前了解以下这些很重要由于scp依赖于s


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

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

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Dreamweaver Mac版
視覺化網頁開發工具