Golang UDP Server and Client Example [Tutorial]

In this tutorial, you'll learn how to UDP server and client using the net package, a component of Go's standard library. The purpose of this manual is to introduce you to the Go programming language through instructional examples.

 

Protocol Definitions and Golang net package

Protocol Description
TCP (Transmission Control Protocol) The main quality of TCP is that it is a reliable protocol by default. TCP will resend a packet if there is no evidence that it was delivered the first time. TCP packets can be used for a variety of purposes, including creating connections, conveying data, sending acknowledgments, and terminating connections.
IP (Internet Protocol) The Internet Protocol (IP) is the network layer communications protocol in the Internet protocol suite for relaying datagrams across network boundaries. Its routing function enables internetworking and essentially establishes the Internet.

Advertisement

IP has the task of delivering packets from the source host to the destination host solely based on the IP addresses in the packet headers. For this purpose, IP defines packet structures that encapsulate the data to be delivered. It also defines addressing methods that are used to label the datagram with source and destination information.

UDP (User Datagram Protocol): While less reliable than TCP, UDP offers a more straightforward implementation of the transport layer protocol that is also significantly faster. UDP is particularly quick since it doesn't offer error checking, correction, or packet retransmission. UDP is typically preferred over TCP when speed is more important than reliability. Online gaming, video chatting, and other real-time applications frequently employ UDP.

net package: Package net provides a portable interface for network I/O, including TCP/IP, UDP, domain name resolution, and Unix domain sockets. Although the package provides access to low-level networking primitives, most clients will need only the basic interface provided by the Dial, Listen, and Accept functions and the associated Conn and Listener interfaces. The crypto/tls package uses the same interfaces and similar Dial and Listen functions.

 

Setting up Golang UDP Server

Create a UDP server and continuously receive packages

We will use ListenPacket() function to create a UDP server:

func ListenPacket(network, address string) (PacketConn, error): ListenPacket announces on the local network address. The network must be "udp", "udp4", "udp6", "unixgram", or an IP transport. The IP transports are "ip", "ip4", or "ip6" followed by a colon and a literal protocol number or a protocol name, as in "ip:1" or "ip:icmp". For UDP and IP networks, if the host in the address parameter is empty or a literal unspecified IP address, ListenPacket listens on all available IP addresses of the local system except multicast IP addresses.

We create a loop for continuously receiving packages. With the help of the Read() function, we can get the data from the UDP client:

udpServer, err := net.ListenPacket("udp", ":1053")
if err != nil {
	log.Fatal(err)
}
defer udpServer.Close()

for {
	buf := make([]byte, 1024)
	_, addr, err := udpServer.ReadFrom(buf)
	if err != nil {
		continue
	}
}

 

Sending the response to the UDP client

We will create a function to send data back to the client with Write() function and wrap it into a go routine:

func response(udpServer net.PacketConn, addr net.Addr, buf []byte) {
	time := time.Now().Format(time.ANSIC)
	responseStr := fmt.Sprintf("time received: %v. Your message: %v!", time, string(buf))

	udpServer.WriteTo([]byte(responseStr), addr)
}

 

Full UDP Server Code

package main

import (
	"fmt"
	"log"
	"net"
	"time"
)

func main() {
	// listen to incoming udp packets
	udpServer, err := net.ListenPacket("udp", ":1053")
	if err != nil {
		log.Fatal(err)
	}
	defer udpServer.Close()

	for {
		buf := make([]byte, 1024)
		_, addr, err := udpServer.ReadFrom(buf)
		if err != nil {
			continue
		}
		go response(udpServer, addr, buf)
	}

}

func response(udpServer net.PacketConn, addr net.Addr, buf []byte) {
	time := time.Now().Format(time.ANSIC)
	responseStr := fmt.Sprintf("time received: %v. Your message: %v!", time, string(buf))

	udpServer.WriteTo([]byte(responseStr), addr)
}

 

Setting up Golang UDP Client

Resolve the UPD Server address, create a connection and close it after finishing communicate

We will use the ResolveUDPAddr() and DialUDP() to establish a connection to the UDP server:

Advertisement

func ResolveUDPAddr(network, address string) (*UDPAddr, error): ResolveUDPAddr returns an address of UDP end point. The network must be a UDP network name.

func DialUDP(network string, laddr, raddr *UDPAddr) (*UDPConn, error): DialUDP acts like Dial for UDP networks. Dial connects to the address on the named network.

udpServer, err := net.ResolveUDPAddr("udp", ":1053")

if err != nil {
	println("ResolveUDPAddr failed:", err.Error())
	os.Exit(1)
}

conn, err := net.DialUDP("udp", nil, udpServer)
if err != nil {
	println("Listen failed:", err.Error())
	os.Exit(1)
}

//close the connection
defer conn.Close()

 

Send and Receive data between the UDP client and server

We can use Write() and Read() function to send and receive messages from the server


_, err = conn.Write([]byte("This is a UDP message"))
if err != nil {
	println("Write data failed:", err.Error())
	os.Exit(1)
}

// buffer to get data
received := make([]byte, 1024)
_, err = conn.Read(received)
if err != nil {
	println("Read data failed:", err.Error())
	os.Exit(1)
}

println(string(received))

 

Full UDP Client Code

package main

import (
	"net"
	"os"
)

const (
	HOST = "localhost"
	PORT = "8080"
	TYPE = "tcp"
)

func main() {
	udpServer, err := net.ResolveUDPAddr("udp", ":1053")

	if err != nil {
		println("ResolveUDPAddr failed:", err.Error())
		os.Exit(1)
	}

	conn, err := net.DialUDP("udp", nil, udpServer)
	if err != nil {
		println("Listen failed:", err.Error())
		os.Exit(1)
	}

	//close the connection
	defer conn.Close()

	_, err = conn.Write([]byte("This is a UDP message"))
	if err != nil {
		println("Write data failed:", err.Error())
		os.Exit(1)
	}

	// buffer to get data
	received := make([]byte, 1024)
	_, err = conn.Read(received)
	if err != nil {
		println("Read data failed:", err.Error())
		os.Exit(1)
	}

	println(string(received))
}

Output:

time received: Wed Nov  2 16:27:56 2022. Your message: This is a UDP message

 

Summary

The UDP client and server example problem was solved in this post using the GoLang programming language. UDP does not have a handshake, and unlike TCP, a UDP socket used for data transfer is not always connected. In the UDP protocol, there is no distinction between clients and servers. Creating a UDP socket or “connection” does not involve sending any packets. A UDP client is simply the initiator, the party that sends the first packet, rather than the responder, the party that receives the first packet.

 

References

https://en.wikipedia.org/wiki/User_Datagram_Protocol
Golang UDP

 

Categories GO

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment

X