Reputation: 87
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.")
Upvotes: 0
Views: 707
Reputation: 7978
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.
Upvotes: 1