英文:
How to drop a UDP connection between server and client from server side in Golang?
问题
我正在尝试找到一种标准的方法来关闭UDP连接中的客户端和服务器之间的连接。
目前,我想到了以下解决方案,但我不确定这是否是一种惯用的方式?
在服务器端(handleClient
函数)中,我正在执行conn.WriteTo(nil, Addr)
,将nil写入UDP地址。在客户端,我检查read()
函数是否检索到任何数据,如果读取的字节数为零,则客户端放弃读取。
if n == 0 || err != nil {
break
}
这是我的简化的Server.go文件:
func handleClient(conn *net.UDPConn) {
b := make([]byte, 1024)
n, Addr, err := conn.ReadFrom(b[0:])
if err != nil {
panic(err)
}
fmt.Println("read:", n, "bytes", Addr.String())
// 将数据写回客户端,仅用于调试目的
conn.WriteTo(b[0:n], Addr)
// 让客户端知道服务器没有更多数据
conn.WriteTo(nil, Addr)
}
这是我的client.go文件:
conn, err := net.Dial("udp", ":14000")
if err != nil {
panic(err)
}
defer conn.Close()
conn.Write([]byte("I'm client "))
for {
b := make([]byte, 512)
n, err := conn.Read(b)
if n == 0 || err != nil {
fmt.Println(">", n, err)
break
}
fmt.Println(string(b))
}
fmt.Println("finished.")
英文:
I'm trying to find a standard way to close a connection between a client and server in a UDP connection.
Currently, I came up with the following solution, however, I'm not sure whether this is an idiomatic way or not?
Basically what I'm doing here on the server-side (handleClient
function) is to conn.WriteTo(nil, Addr)
which write nil to the UDP address. on the client side I check if the read()
function retrieved any data or not, in case the number of the reading byte is zero, the client gives up on reading.
if n ==0 || err != nil {
break
}
Here is my simplified Server.go file:
func handleClient(conn *net.UDPConn) {
b := make([]byte, 1024)
n, Addr, err := conn.ReadFrom(b[0:])
if err != nil {
panic(err)
}
fmt.Println("read: ", n, " bytes", Addr.String())
// write the data back to the client, just for debug purpose
conn.WriteTo(b[0:n], Addr)
// let the client know that server has no more data
conn.WriteTo(nil, Addr)
}
conn, err := net.Dial("udp", ":14000")
if err != nil {
panic(err)
}
defer conn.Close()
conn.Write([]byte("I'm client "))
for {
b := make([]byte, 512)
n, err := conn.Read(b)
if n ==0 || err != nil {
fmt.Println(">", n, err)
break
}
fmt.Println(string(b))
}
fmt.Println("finished.")
答案1
得分: 1
没有标准的方法来实现这个。UDP是一种无状态协议,所以没有像TCP连接那样的"连接"。例如,DNS没有状态的概念,客户端发送请求,服务器响应,没有维护状态,这通常是UDP的卖点。
应用程序负责维护状态,所以如果你想在UDP之上实现一个有状态的协议,你也必须自己处理关闭这样一个连接的操作。你可以从FTP或TFTP中获取灵感,看看如何实现这一点。或者考虑使用像TCP或QUIC这样的有状态传输层协议来处理有状态的连接。
英文:
There is no standard way to do this. UDP is a stateless protocol so there is no "connection" like you would have with a TCP connection. DNS for example has no concept of a state, a client sends a request and the server will respond, no state is maintained, this is usually the selling point of UDP.
The applications are responsible for maintain state, so if you want a stateful protocol on top of UDP you also have to handle closing such a connection yourself. You might take inspiration from FTP or TFTP on how to implement this. Or consider using a stateful transport layer protocol like TCP or QUIC to handle stateful connections for you.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论