英文:
Request/response conversation using UDPConn
问题
我正在尝试实现以下UDP协议,但是我在确定应该如何处理时遇到了一些困难。
协议规定我应该向特定服务器发送一个特定的UDP数据包,之后服务器将以UDP数据包的形式流式传输(多个相关的UDP数据包)回应给我。我已经成功使用以下代码发送了UDP数据包:
connection, error := net.DialUDP("udp", nil, endpoint)
...
if written, error := connection.Write(query.ToBytes()); error != nil {
...
} else {
log.Printf("成功写入 %d 字节到 %s", written, connection.RemoteAddr())
}
当我使用Wireshark查看传输的内容时,看起来它成功发送了数据包(唯一的问题是我从服务器那里没有收到回复,但这与本问题无关)。
在这种情况下,我应该如何处理服务器的回复?我可以使用之前建立的connection
来读取服务器的回复吗(这对我来说似乎不太可能,因为UDP是无连接的),还是应该使用net.ListenUDP(...)
在正确的本地地址和端口上建立一个服务器来读取服务器发送给我的内容?
英文:
I'm trying to implement the following UDP protocol, but I'm having a little trouble figuring exactly how I should approach this.
The protocol states that I should send a particular UDP packet to a certain server, after which the server will stream (several UDP packets that are related) a response back to me, also as UDP packets. I have managed to send the UDP packet fine using the following code:
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())
}
When I use Wireshark and take a look at what's going over the wire, it looks like it sent the packet just fine (the only issue here is that I never get a reply from the server, but that's unrelated to this question).
What's the best way for me to handle the server reply in this case? Can I use the previously established connection
to read server responses back (this seems unlikely to me, as it's UDP so connectionless) or should I use net.ListenUDP(...)
to establish a server on the correct local address and port to read whatever the server sends back to me?
答案1
得分: 1
协议的意图很明确,即您只需使用相同的UDP套接字来接收您发送请求的回复。如果您有客户端防火墙,您将需要显式打开一个UDP端口,并将UDP套接字绑定到该端口,然后再发送请求。否则,只需让系统选择本地端口,不进行任何绑定。
短语“与初始数据包建立的相同端口”是具有误导性的。这是您的措辞还是协议规范的措辞?当您进行第一次发送时,实际发生的是,如果您尚未绑定套接字,它将自动绑定到系统选择的端口,就像您将其绑定到端口零一样。
英文:
The intent of the protocol is clearly that you just use the same UDP socket to receive the reply that you used to send the request. If you have a client-side firewall, you will have to explicitly open a UDP port and bind the UDP socket to that port before you send. Otherwise just let the system choose the local port, by not binding at all.
The phrase 'the same port as was established by the intial packet' is misleading. Are they your words, or the protocol specification's? What really happens when you do the first send is that if you haven't bound the socket yet, it is automatically bound to a system-chosen port, exactly as if you had bound it to port zero.
答案2
得分: 0
由于特定的协议设计,无法知道服务器将在哪个端口发送其回复数据包。在仔细查看数据包转储后,我注意到服务器实际上确实会回复,只是客户端立即回复一个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
,例如读取服务器发送的数据包。
英文:
Because of the specific protocol design, it's impossible to know on which port the server will send its reply packets. After taking a second look at the packet dumps, I noticed that the server in fact does reply, only the client immediately replies back with an ICMP message saying Destination port unreachable
. So the server was trying to reply, but it couldn't because the client would not accept the packets on that port.
To solve this, I have used net.ListenUDP
to listen for incoming packets immediately after the client sends the initial packet using the established connection's local address:
incomingConnection, _ := net.ListenUDP("udp", connection.LocalAddr().(*net.UDPAddr))
log.Printf("Listening for packets on %s", incomingConnection.LocalAddr())
defer incomingConnection.Close()
After which incomingConnection
can be used as a Reader
- for example - read the packets that the server is sending.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论