我正在尝试实现以下UDP协议,但我在确定如何处理此问题时遇到了一些麻烦。
该协议声明我应该将特定的UDP数据包发送到某个服务器,之后服务器将流(几个相关的UDP数据包)回复给我,也作为UDP数据包。我已设法使用以下代码发送UDP数据包:
connection, error := net.DialUDP("udp", nil, endpoint)
...
if written, error := connection.Write(query.ToBytes()); error != nil {
...
} else {
log.Printf("Successfully wrote %d bytes to %s", written, connection.RemoteAddr())
}
当我使用Wireshark并查看线路上的内容时,看起来它发送的数据包很好(这里唯一的问题是我从未收到服务器的回复,但这与此问题无关)
在这种情况下,我处理服务器回复的最佳方式是什么?我可以使用先前建立的connection
来读取服务器响应(这似乎不太可能,因为它是UDP无连接)或者我应该使用net.ListenUDP(...)
在正确的本地地址和端口上建立服务器阅读服务器发回给我的任何内容?
答案 0 :(得分:1)
协议的意图显然是您只使用相同的UDP套接字来接收您用于发送请求的回复。如果您有客户端防火墙,则必须在发送之前显式打开UDP端口并将UDP套接字绑定到该端口。否则,让系统选择本地端口,完全不绑定。
短语'与初始数据包建立的端口相同'是误导性的。他们是你的话,还是协议规范?第一次发送时真正发生的事情是,如果你还没有绑定套接字,它会自动绑定到系统选择的端口,就像你将它绑定到端口零一样。
答案 1 :(得分:0)
由于特定的协议设计,无法知道服务器将在哪个端口发送其回复数据包。在第二次查看数据包转储后,我注意到服务器实际上做了回复,只有客户端立即回复了一条说明Destination port unreachable
的ICMP消息。所以服务器试图回复,但它不能,因为客户端不会接受该端口上的数据包。
为了解决这个问题,我使用net.ListenUDP
在客户端使用已建立的连接的本地地址发送初始数据包后立即侦听传入的数据包:
incomingConnection, _ := net.ListenUDP("udp", connection.LocalAddr().(*net.UDPAddr))
log.Printf("Listening for packets on %s", incomingConnection.LocalAddr())
defer incomingConnection.Close()
之后incomingConnection
可以用作Reader
- 例如 - 读取服务器正在发送的数据包。