无法读取UDP回复(golang)

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

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)

huangapple
  • 本文由 发表于 2016年12月1日 04:19:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/40897417.html
匿名

发表评论

匿名网友

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

确定