This package provides a simple wrapper over the UDP multicast functions in net. The two primary reasons one might want to use this package are:
-
Watching for network interfaces being added or removed (via
Watcher) -
The ability to mock network access, allowing packages to easily test the implementation of their network code as-is (via
MockandUnmock)
import "github.com/nitroshare/gomulticast"
// Get a slice of network interfaces available
ifaces, err := gomulticast.Interfaces()
if err != nil {
panic(err)
}
// Find the first one that can multicast
var iface gomulticast.Interface
for _, i := range ifaces {
if i.Interface().Flags & net.FlagMulticast != 0 {
iface = i
break
}
}
if iface == nil {
panic("no multicast interfaces found")
}
// Multicast address
addr := &net.UDPAddr{
IP: net.IP([]byte{1, 2, 3, 4}),
Port: 1234,
}
// Create a listener for sending and receiving packets
l, err := gomulticast.NewListener("udp4", iface, addr)
if err != nil {
panic(err)
}
defer l.Close()
// Send a packet
l.Write(&gomulticast.Packet{
Addr: addr,
Data: []byte("test data"),
})
// Read a packet (this blocks)
p, _ := l.Read()The network interfaces present on a system can change during runtime (for example, a USB Wi-Fi adapter hot-plugged). In order to support these events, Watcher is provided:
// Poll for interfaces being added / removed every 30s
w := gomulticast.NewWatcher(30 * time.Second)
defer w.Close()
// Print a message when an interface is added or removed; in a real
// application, you'd probably want to create a new Listener when an
// interface is added
for {
select {
case i := <-w.ChanAdded:
fmt.Printf("%s added!", i.Interface().Name)
case i := <-w.ChanRemoved:
fmt.Printf("%s removed!", i.Interface().Name)
}
}If for example you wanted to test the code above without modifying it or relying on the host's network stack, gomulticast has you covered (no pun intended)!
// Mock everything in the package
gomulticast.Mock()
defer gomulticast.Unmock()
// Create a mocked interface and make future calls to Interfaces() return it
i := gomulticast.NewMockInterface()
gomulticast.AddMockInterface(i)
// Now whenever Interfaces() is called, this will be the only one returned
// Packets can be queued for reading from it...
i.QueueForRead(&gomulticast.Packet{...})
// ...and packets written to it can be dequeued
p, _ := i.DequeueWrite()