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