Skip to content
This repository has been archived by the owner on Nov 18, 2023. It is now read-only.

aler9/howto-udp-broadcast-golang

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 

Repository files navigation

Howto: UDP broadcast in Go

Sample code and instructions on how to send and receive UDP broadcast packets in the Go programming language.

Introduction

A common method to trasmit informations to multiple devices connected to the same network consists in using the UDP transport layer and sending the packets to the network broadcast address. The router will take care of propagating the packets to each connected device. There are at least two advantages with respect to normal network communication:

  • transmission is much more efficient, as a single stream of data is used for communicating with multiple devices
  • it is not necessary to know in advance the addresses of the recipients

The Go programming languages offers at least 4 ways to send UDP broadcast packets, the situation is not very clear and that's the reason why this guide is being written.

Sending

Let's assume we want to transmit the ascii-encoded phrase "data to transmit" though port 8829 in a network with IP 192.168.7.2 and broadcast address 192.168.7.255.

The first (and preferred) method consists in using the net.ListenPacket() function:

package main

import (
  "net"
  "fmt"
)

func main() {
  pc, err := net.ListenPacket("udp4", ":8829")
  if err != nil {
    panic(err)
  }
  defer pc.Close()

  addr,err := net.ResolveUDPAddr("udp4", "192.168.7.255:8829")
  if err != nil {
    panic(err)
  }

  _,err := pc.WriteTo([]byte("data to transmit"), addr)
  if err != nil {
    panic(err)
  }
}

A second method consists in using the net.ListenUDP() function:

package main

import (
  "net"
)

func main() {
  listenAddr,err := net.ResolveUDPAddr("udp4", ":8829")
  if err != nil {
    panic(err)
  }
  list, err := net.ListenUDP("udp4", listenAddr)
  if err != nil {
    panic(err)
  }
  defer list.Close()

  addr,err := net.ResolveUDPAddr("udp4", "192.168.7.255:8829")
  if err != nil {
    panic(err)
  }

  _,err := list.WriteTo([]byte("data to transmit"), addr)
  if err != nil {
    panic(err)
  }
}

A third method consists in using the net.DialUDP() function:

package main

import (
  "net"
)

func main() {
  local,err := net.ResolveUDPAddr("udp4", ":8829")
  if err != nil {
    panic(err)
  }
  remote,err := net.ResolveUDPAddr("udp4", "192.168.7.255:8829")
  if err != nil {
    panic(err)
  }
  list, err := net.DialUDP("udp4", local, remote)
  if err != nil {
    panic(err)
  }
  defer list.Close()

  _,err := list.Write([]byte("data to transmit"))
  if err != nil {
    panic(err)
  }
}

A fourth and shorter way consists in using the net.Dial() function if the local address / port don't matter:

package main

import "net"

func main() {
  conn, err := net.Dial("udp", "192.168.7.255:8829")
  if err != nil {
    panic(err)
  }
  defer conn.Close()
  
  _, err := conn.Write([]byte("data to transmit"))
  if err != nil {
    panic(err)
  }

All four methods work and their result is indistinguishable. By looking at the Go source code, it is possible to assert that:

  • net.ListenPacket() and net.ListenUDP() use a nearly identical identical procedure, as they both call the same system functions, the only difference is that net.ListenPacket() converts the desired listen address (:8829) into an UDPAddr structure, while net.ListenUDP() requires directly an UDPAddr structure;
  • net.DialUDP() uses a different route and also provides a Write() function to write directly to the broadcast address. This could be confusing, as Go always work with WriteTo() and ReadFrom() when dealing with UDP connections.

Conclusion: I use with the ListenPacket() solution as it is the simpler one.

Receiving

Data can be received with a standard UDP server listening on the provided port:

package main

import (
  "fmt"
  "net"
)

func main() {
  pc,err := net.ListenPacket("udp4", ":8829")
  if err != nil {
    panic(err)
  }
  defer pc.Close()

  buf := make([]byte, 1024)
  n,addr,err := pc.ReadFrom(buf)
  if err != nil {
    panic(err)
  }
  
  fmt.Printf("%s sent this: %s\n", addr, buf[:n])
}

About

Sample code and instructions on how to send and receive UDP broadcast packets in the Go programming language.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published