@@ -9,64 +9,74 @@ import (
99
1010const maxDatagramSize = 8192
1111
12- type MulticastReceiver struct {
13- activeIfis map [string ]bool
14- connections []* net.UDPConn
12+ type MulticastServer struct {
13+ connection * net.UDPConn
1514 running bool
1615 consumer func ([]byte )
1716 mutex sync.Mutex
1817 SkipInterfaces []string
18+ Verbose bool
1919}
2020
21- func NewMulticastReceiver (consumer func ([]byte )) (r * MulticastReceiver ) {
22- r = new (MulticastReceiver )
23- r .activeIfis = map [string ]bool {}
21+ func NewMulticastServer (consumer func ([]byte )) (r * MulticastServer ) {
22+ r = new (MulticastServer )
2423 r .consumer = consumer
2524 return
2625}
2726
28- func (r * MulticastReceiver ) Start (multicastAddress string ) {
27+ func (r * MulticastServer ) Start (multicastAddress string ) {
2928 r .running = true
3029 go r .receive (multicastAddress )
3130}
3231
33- func (r * MulticastReceiver ) Stop () {
32+ func (r * MulticastServer ) Stop () {
3433 r .mutex .Lock ()
3534 defer r .mutex .Unlock ()
3635 r .running = false
37- for _ , c := range r .connections {
38- if err := c .Close (); err != nil {
39- log .Println ("Could not close connection: " , err )
40- }
36+ if err := r .connection .Close (); err != nil {
37+ log .Println ("Could not close connection: " , err )
4138 }
4239}
4340
44- func (r * MulticastReceiver ) receive (multicastAddress string ) {
41+ func (r * MulticastServer ) receive (multicastAddress string ) {
42+ log .Printf ("Receiving on %v" , multicastAddress )
43+ var currentIfiIdx = 0
4544 for r .isRunning () {
46- ifis , _ := net .Interfaces ()
47- for _ , ifi := range ifis {
48- if ifi .Flags & net .FlagMulticast == 0 || // No multicast support
49- r .skipInterface (ifi .Name ) {
50- continue
51- }
52- r .mutex .Lock ()
53- if _ , ok := r .activeIfis [ifi .Name ]; ! ok {
54- // interface not active, (re-)start receiving
55- go r .receiveOnInterface (multicastAddress , ifi )
56- }
57- r .mutex .Unlock ()
45+ ifis := r .interfaces ()
46+ currentIfiIdx = currentIfiIdx % len (ifis )
47+ ifi := ifis [currentIfiIdx ]
48+ r .receiveOnInterface (multicastAddress , ifi )
49+ currentIfiIdx ++
50+ if currentIfiIdx >= len (ifis ) {
51+ // cycled though all interfaces once, make a short break to avoid producing endless log messages
52+ time .Sleep (1 * time .Second )
5853 }
59- time .Sleep (1 * time .Second )
6054 }
6155}
6256
63- func (r * MulticastReceiver ) isRunning () bool {
57+ func (r * MulticastServer ) isRunning () bool {
6458 r .mutex .Lock ()
6559 defer r .mutex .Unlock ()
6660 return r .running
6761}
6862
69- func (r * MulticastReceiver ) skipInterface (ifiName string ) bool {
63+ func (r * MulticastServer ) interfaces () (interfaces []net.Interface ) {
64+ interfaces = []net.Interface {}
65+ ifis , err := net .Interfaces ()
66+ if err != nil {
67+ log .Println ("Could not get available interfaces: " , err )
68+ }
69+ for _ , ifi := range ifis {
70+ if ifi .Flags & net .FlagMulticast == 0 || // No multicast support
71+ r .skipInterface (ifi .Name ) {
72+ continue
73+ }
74+ interfaces = append (interfaces , ifi )
75+ }
76+ return
77+ }
78+
79+ func (r * MulticastServer ) skipInterface (ifiName string ) bool {
7080 for _ , skipIfi := range r .SkipInterfaces {
7181 if skipIfi == ifiName {
7282 return true
@@ -75,52 +85,55 @@ func (r *MulticastReceiver) skipInterface(ifiName string) bool {
7585 return false
7686}
7787
78- func (r * MulticastReceiver ) receiveOnInterface (multicastAddress string , ifi net.Interface ) {
88+ func (r * MulticastServer ) receiveOnInterface (multicastAddress string , ifi net.Interface ) {
7989 addr , err := net .ResolveUDPAddr ("udp" , multicastAddress )
8090 if err != nil {
8191 log .Printf ("Could resolve multicast address %v: %v" , multicastAddress , err )
8292 return
8393 }
8494
85- listener , err : = net .ListenMulticastUDP ("udp" , & ifi , addr )
95+ r . connection , err = net .ListenMulticastUDP ("udp" , & ifi , addr )
8696 if err != nil {
8797 log .Printf ("Could not listen at %v: %v" , multicastAddress , err )
8898 return
8999 }
90100
91- if err := listener .SetReadBuffer (maxDatagramSize ); err != nil {
101+ if err := r . connection .SetReadBuffer (maxDatagramSize ); err != nil {
92102 log .Println ("Could not set read buffer: " , err )
93103 }
94104
95- r .mutex .Lock ()
96- r .connections = append (r .connections , listener )
97- r .activeIfis [ifi .Name ] = true
98- r .mutex .Unlock ()
99-
100- log .Printf ("Listening on %s (%s)" , multicastAddress , ifi .Name )
105+ if r .Verbose {
106+ log .Printf ("Listening on %s (%s)" , multicastAddress , ifi .Name )
107+ }
101108
109+ first := true
102110 data := make ([]byte , maxDatagramSize )
103111 for {
104- n , _ , err := listener .ReadFrom (data )
112+ if err := r .connection .SetDeadline (time .Now ().Add (300 * time .Millisecond )); err != nil {
113+ log .Println ("Could not set deadline on connection: " , err )
114+ }
115+ n , _ , err := r .connection .ReadFromUDP (data )
105116 if err != nil {
106- log .Println ("ReadFromUDP failed:" , err )
117+ if r .Verbose {
118+ log .Println ("ReadFromUDP failed:" , err )
119+ }
107120 break
108121 }
109122
123+ if first {
124+ log .Printf ("Got first data packets from %s (%s)" , multicastAddress , ifi .Name )
125+ first = false
126+ }
127+
110128 r .consumer (data [:n ])
111129 }
112130
113- log .Printf ("Stop listening on %s (%s)" , multicastAddress , ifi .Name )
131+ if r .Verbose {
132+ log .Printf ("Stop listening on %s (%s)" , multicastAddress , ifi .Name )
133+ }
114134
115- if err := listener .Close (); err != nil {
135+ if err := r . connection .Close (); err != nil {
116136 log .Println ("Could not close listener: " , err )
117137 }
118- r .mutex .Lock ()
119- delete (r .activeIfis , ifi .Name )
120- for i , c := range r .connections {
121- if c == listener {
122- r .connections = append (r .connections [:i ], r .connections [i + 1 :]... )
123- }
124- }
125- r .mutex .Unlock ()
138+ return
126139}
0 commit comments