英文:
Can't read UDP reply (golang)
问题
我正在处理一个Go程序,它发送一个UDP广播来查询本地网络上设备的存在,并读取回复。使用Wireshark,我确认数据包是广播的,并且网络上的单个设备(我的设备)确实回复了(实际上回复了十次),但我的应用程序在读取时阻塞,就好像它没有看到传入的数据包一样。以下是代码:
func Discover(timeout int) ([]string, error) {
inBuf := make([]byte, 1024)
devices := make([]string, 0)
var readLen int
var fromAddr *net.UDPAddr
// 获取服务器连接
server := fmt.Sprintf("%s:%d", bcastIP, udpDiscoverPort) // "255.255.255.255", 10000
serverAddr, err = net.ResolveUDPAddr("udp", server)
checkErr(err)
ourAddr, err = net.ResolveUDPAddr("udp", "192.168.1.132:10000")
checkErr(err)
conn, err = net.DialUDP("udp", ourAddr, serverAddr)
checkErr(err)
defer conn.Close()
// 发送Discover消息
discoverMsg := []byte(magic)
discoverMsg = append(discoverMsg, discovery...)
sendLen, err := conn.Write(discoverMsg)
checkErr(err)
fmt.Println("Sent", sendLen, "bytes")
// 读取一个回复
readLen, fromAddr, err = conn.ReadFromUDP(inBuf)
fmt.Println("Read", readLen, "bytes from", fromAddr)
txtutil.Dump(string(inBuf[:readLen]))
return devices, nil
}
checkErr(err)如果err不为nil,则打印诊断信息并退出。
回复中的信息如下所示:
Internet Protocol Version 4, Src: 192.168.1.126 (192.168.1.126), Dst: 192.168.1.132 (192.168.1.132)
User Datagram Protocol, Src Port: ndmp (10000), Dst Port: ndmp (10000)
我尝试过在"192.168.1.132:10000"的位置使用"0.0.0.0:10000"、":10000"和"127.0.0.1:10000",但似乎没有任何区别。
欢迎提出任何关于我做错了什么的建议!
英文:
I'm working on a Go program that sends out a UDP broadcast to query existence of devices on the local network and then reads the replies. Using Wireshark I confirm that the packet is broadcast and that the single device on (my) network replies (ten times, in fact) but my application blocks on the read as if it does not see the incoming packet. Here is the code:
func Discover(timeout int) ([]string, error) {
inBuf := make([]byte, 1024)
devices := make([]string, 0)
var readLen int
var fromAddr *net.UDPAddr
// get server connection
server := fmt.Sprintf("%s:%d", bcastIP, udpDiscoverPort) // "255.255.255.255", 10000
serverAddr, err = net.ResolveUDPAddr("udp", server)
checkErr(err)
ourAddr, err = net.ResolveUDPAddr("udp", "192.168.1.132:10000")
checkErr(err)
conn, err = net.DialUDP("udp", ourAddr, serverAddr)
checkErr(err)
defer conn.Close()
// send the Discover message
discoverMsg := []byte(magic)
discoverMsg = append(discoverMsg, discovery...)
sendLen, err := conn.Write(discoverMsg)
checkErr(err)
fmt.Println("Sent", sendLen, "bytes")
// read one reply
readLen, fromAddr, err = conn.ReadFromUDP(inBuf)
fmt.Println("Read ", readLen, "bytesfrom ", fromAddr)
txtutil.Dump(string(inBuf[:readLen]))
return devices, nil
}
checkErr(err) prints a diagnostic and exits if err is not nil, BTW.
The information in the replies looks like:
Internet Protocol Version 4, Src: 192.168.1.126 (192.168.1.126), Dst: 192.168.1.132 (192.168.1.132)
User Datagram Protocol, Src Port: ndmp (10000), Dst Port: ndmp (10000)
I have tried "0.0.0.0:10000", ":10000" and "127.0.0.1:10000" in place of "192.168.1.132:10000" and none seem to make any difference.
Any suggestions as to what I'm doing wrong are welcome!
答案1
得分: 4
你需要使用ListenUDP
而不是DialUDP
。当你使用DialUDP
时,它创建了一个"连接"的UDP端口,只有来自远程地址的数据包才会在读取时返回。
conn, err = net.ListenUDP("udp", ourAddr)
由于连接没有默认目标地址,你还需要使用WriteTo*
方法发送数据包:
sendLen, err := conn.WriteToUDP(discoverMsg, serverAddr)
英文:
You need to use ListenUDP
instead of DialUDP
. When you use DialUDP
, it creates a "connected" UDP port, and only packets originating from the remote address are returned on read.
conn, err = net.ListenUDP("udp", ourAddr)
Since the connection doesn't have a default destination, you will also need to use WriteTo*
methods to send packets:
sendLen, err := conn.WriteToUDP(discoverMsg, serverAddr)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论