Skip to content

nitroshare/gomulticast

Repository files navigation

gomulticast

Build Status Coverage Status Go Reference MIT License

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 Mock and Unmock)

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()

Watching for Interfaces

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)
    }
}

Mock Interfaces

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()

About

Simple wrapper over UDP multicast functionality with easy mocking capabilities

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages