JoinGroup -> ListenMulticastUDP how?

693 views
Skip to first unread message

Jeffrey Baker

unread,
Mar 6, 2012, 1:36:32 AM3/6/12
to golan...@googlegroups.com
I had written some Go code to control my Sonos media player, which uses uPnP interfaces.  In the uPnP discovery phase, my program used to listen on a UDP port and join a multicast address, then send an HTTP request in a multicast UDP packet to 239.255.255.250:1900.  The Sonos thing sends back an HTTP response in a unicast UDP packet destined for the port my program sends from.  Basically:

mcaddr, err := net.ResolveUDPAddr("udp4", "239.255.255.250:1900")
laddr, err := net.ResolveUDPAddr("udp4", ":62756")
c, err := net.ListenUDP("udp4", laddr)
err = c.JoinGroup(mcaddr.IP)
c.WriteTo(req, mcaddr)

This week, I wanted some stuff that is in the weekly but not release, so I pulled the weekly go source.  I don't understand where the new ListenMulticastUDP function fits in.  I want to join the multicast address, but I don't think I care about the port.  The old JoinGroup took an IP, but the new ListenMulticastUDP wants an IP and port both.  Does it make any difference what I give it for the port?  I specifically do _not_ want to listen on port 1900.

Everything _seems_ to be working with this instead of c.JoinGroup:

junk, err := net.ListenMulticastUDP("udp", nil, &net.UDPAddr{IP: mcaddr.IP})

Except that I now have to babysit the lifecycle of "junk" connection that I don't need (including the obligatory junk = junk, to make it not unused).  Am I using this interface correctly?

-jwb

Mikio Hara

unread,
Mar 6, 2012, 3:17:52 AM3/6/12
to Jeffrey Baker, golan...@googlegroups.com
Hi,

On Tue, Mar 6, 2012 at 3:36 PM, Jeffrey Baker <jwb...@gmail.com> wrote:

> ListenMulticastUDP function fits in.  I want to join the multicast address,
> but I don't think I care about the port.  The old JoinGroup took an IP, but
> the new ListenMulticastUDP wants an IP and port both.  Does it make any
> difference what I give it for the port?

No it doesn't.

> junk, err := net.ListenMulticastUDP("udp", nil, &net.UDPAddr{IP: mcaddr.IP})
>
> Except that I now have to babysit the lifecycle of "junk" connection that I
> don't need (including the obligatory junk = junk, to make it not unused).
>  Am I using this interface correctly?

I guess you need that "junk" to send multicast UDP packets to
on-link multicast neighbors. (or am I missing something?)

package main

import (
"log"
"net"
)

func main() {
nbrs, err := net.ResolveUDPAddr("udp4", "239.255.255.250:1900")
if err != nil {
log.Fatal(err)
}
c, err := net.ListenMulticastUDP("udp4", nil, &net.UDPAddr{IP:
net.IPv4(239, 255, 255, 250)})
if err != nil {
log.Fatal(err)
}
_, err := c.WriteTo([]byte("hello, on-link neighbors!"), nbrs)
if err != nil {
log.Fatal(err)
}
}

Jeffrey Baker

unread,
Mar 6, 2012, 4:26:51 PM3/6/12
to Mikio Hara, golan...@googlegroups.com
On Tue, Mar 6, 2012 at 12:17 AM, Mikio Hara <mikioh...@gmail.com> wrote:
Hi,

On Tue, Mar 6, 2012 at 3:36 PM, Jeffrey Baker <jwb...@gmail.com> wrote:

> ListenMulticastUDP function fits in.  I want to join the multicast address,
> but I don't think I care about the port.  The old JoinGroup took an IP, but
> the new ListenMulticastUDP wants an IP and port both.  Does it make any
> difference what I give it for the port?

No it doesn't.

> junk, err := net.ListenMulticastUDP("udp", nil, &net.UDPAddr{IP: mcaddr.IP})
>
> Except that I now have to babysit the lifecycle of "junk" connection that I
> don't need (including the obligatory junk = junk, to make it not unused).
>  Am I using this interface correctly?

I guess you need that "junk" to send multicast UDP packets to
on-link multicast neighbors. (or am I missing something?)

The thing with uPnP is the reply comes back unicast.  So I don't care about receiving on the multicast address, I only need to send to it.  In the old interface, I could ListenUDP on a bare port like :12345, JoinGroup on the multicast address, send to it, and receive the unicast reply all on the same UDPConn.  In the new API, I need a UDPConn for sending and receiving, as well as another UDPConn just for joining the multicast groups, which is never read nor written.
 
       c, err := net.ListenMulticastUDP("udp4", nil, &net.UDPAddr{IP:
net.IPv4(239, 255, 255, 250)})
       _, err := c.WriteTo([]byte("hello, on-link neighbors!"), nbrs)

That works too, I guess.  I can write on the listening multicast connection, and read from the unicast one.  At least that will make me feel better about having two connections :-)

-jwb 
Reply all
Reply to author
Forward
0 new messages