Reputation: 635
I am trying to send a UDP multicast message from my container-1 and trying to receive it on container2.I have linked container-2 with container-1 using --link
option .I am using these sample codes for testing
multicastsend.py
import socket
MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007
regarding socket.IP_MULTICAST_TTL
# ---------------------------------
# for all packets sent, after two hops on the network the packet will not
# be re-sent/broadcast (see https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html)
MULTICAST_TTL = 2
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL)
# For Python 3, change next line to 'sock.sendto(b"robot", ...' to avoid the
# "bytes-like object is required" msg (https://stackoverflow.com/a/42612820)
sock.sendto(b"robot", (MCAST_GRP, MCAST_PORT))
multicastrec.py
import socket
import struct
MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007
IS_ALL_GROUPS = True
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if IS_ALL_GROUPS:
# on this port, receives ALL multicast groups
sock.bind(('', MCAST_PORT))
else:
# on this port, listen ONLY to MCAST_GRP
sock.bind((MCAST_GRP, MCAST_PORT))
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
while True:
# For Python 3, change next line to "print(sock.recv(10240))"
print (sock.recv(10240))
The port 5007 on container-2(receiver) is published using -p 5007:5007/udp
option with docker run
When i run sender and receiver on the same container messages are getting published and received properly .But when running in two different containers messages are not getting received
when running these containers with --network=host
option we are able to establish the connection . But is there any way to make this happen with default Bridge network of docker
Upvotes: 1
Views: 933
Reputation: 2863
These lines don't do what you think they do:
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
INADDR_ANY
is the wildcard address, but when used with IP_ADD_MEMBERSHIP
that just means that it will pick the 'default' interface--not all interfaces. If you want to add all interfaces, you will need to loop over all of your interfaces and add membership explicitly for each of them. In your case, you probably just want to add membership with docker bridge ip for that container.
Something like this worked for me:
bridge_ip = "172.19.0.1" # change this to match the bridge IP for your container
sock.setsockopt(
socket.SOL_IP,
socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(MCAST_GRP) + socket.inet_aton(bridge_ip),
)
I the exact same question you had and found the following answers which helped me:
for the insight that INADDR_ANY does not mean all: https://stackoverflow.com/a/46075375/2069572
for the syntax to IP_ADD_MEMBERSHIP a specific address https://stackoverflow.com/a/6102513/2069572
If you really do want to add all of your interfaces, you will need to do that in a loop. This answer will get you on the right track for figuring out how to get all the addresses associated with your interfaces: https://stackoverflow.com/a/24196955/2069572
Upvotes: 2