Joining a multicast group w UDPSocket

Hello CR community,

im trying to build a multicast listener to test for market data connectivity

lets say I have a server with a local iface address of 192.168.38.38

I want to join a Mcast group of 233.4.3.2 port 9000 to see if Im receiving any market data or datagrams

I tried writing a simple listener like this, but am unable to get it to join a group over a specific interface,


require "socket"

MULTICAST_ADDR = "233.4.3.2"
PORT           = 9000
IFACE          = "192.168.38.38"

sock = UDPSocket.new

sock.reuse_address = true
sock.reuse_port = true
sock.read_timeout = 30.seconds

mcaddr = Socket::IPAddress.new(MULTICAST_ADDR, PORT)

## attempt to bind to MC group over specific iface
mreq = Socket::IPAddress.new(MULTICAST_ADDR, PORT).to_s + Socket::IPAddress.new(IFACE, PORT).to_s

## set socket option with mreq (this doesnt work properly)
sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP, socket.IP_ADD_MEMBERSHIP, mreq)

sock.bind MULTICAST_ADDR, PORT
sock.join_group(mcaddr)

# largest packets seem to be 4096 * 15
bytes = Bytes.new(4096 * 20)

buffer = uninitialized UInt8[2048]

while (1 == 1)
  bytes, payload = sock.receive buffer.to_slice
  msg = String.new(buffer.to_slice[0, bytes])
  puts msg
end

having issues with mreq part and socket options, just not sure how to replicate something like this thats in written in python, this works btw,

want to basically replicate this in crystal, thanks

#!python3
MULTICAST_ADDR = "233.4.3.2"
PORT  = 9000
IFACE  = "192.168.38.38"

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)
ttl = struct.pack('b', 1)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)

mreq = socket.inet_aton(MULTICAST_ADDR) + socket.inet_aton(IFACE)  # 

sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
sock.settimeout(45) # timeout after 45sec

while True:
    try:
        sock.bind((MULTICAST_ADDR, PORT))
        data, addr = sock.recvfrom(PORT)
    except socket.timeout:
        print("Timed out", f"{MULTICAST_ADDR}:{PORT}", IFACE)
        break
    except socket.error:
        print(f"Invalid Group {MULTICAST_ADDR}:{PORT} on {IFACE} {RESET}")
        return 1

    else:
        print("Received", f"{MULTICAST_ADDR}:{PORT}", IFACE)
        break
    finally:
        sock.close()

I don’t have the answer to this but this is an interesting subject. Did you ever figure this out?

1 Like