GoLang UDP Service Example

2020-11-15 18:53:00
Taotao
Original 4500
Summary : In order to avoid processing each layer of data, GoLang creates a copy of the same data in memory. It is passed by reference. That is the point of "slice"! It saves a lot of memory!

The common demo of GoLang UDP is,



conn, err := net.ListenUDP("udp", &net.UDPAddr{Port: 8866})
if err != nil {
	log.Fatalf("Udp Service listen report udp fail:%v", err)
}
defer conn.Close()
for {
	data := make([]byte, 1024*4)
	n, remoteAddr, err := conn.ReadFromUDP(data)
	if err == nil {
		// ... do something
           conn.WriteToUDP(data[:n], remoteAddr)
	}
}
The problem of the demo is,



  1. It consumes a lot of memory
  2.  It causes frequent GC.

The solution is



In order to avoid processing each layer of data, GoLang creates a copy of the same data in memory. It is passed by reference. That is the point of slice! It saves a lot of memory! 
The data after conn.ReadFromUDP(data) is actually the data reference in the underlying buffer. Operating data is actually operating the underlying buffer.
Therefore, the data in "data" must be read into a new variable before privatizing it and sending it for coroutine. Otherwise, the data in "data“ may be refreshed because it enters a new cycle before the coroutine is started!
Unfortunately, the simple way cannot privatize "data". You can only make a blank slice, and then copy the data one by one. GoLang has encapsulated a function for us, which is "copy".


conn, err := net.ListenUDP("udp", &net.UDPAddr{Port: 8866})
if err != nil {
	log.Fatalf("Udp Service listen report udp fail:%v", err)
}
defer conn.Close()
var data = make([]byte, 1024*4)
var raw []byte
for {
	n, remoteAddr, err := conn.ReadFromUDP(data)
	if err == nil {
		raw = make([]byte,n)
		copy(raw,data[:n])
		go func (){
			// ... use raw to do something
			conn.WriteToUDP(raw, remoteAddr)
		}()
	}
}





Write a Comment
Comment will be posted after it is reviewed.