1
votes

Python multicast receiver running on windows 2012 server is not getting udp traffic. I inspected traffic and I see the udp traffic is coming across. I have a firewall udp rule for the multicast group with edge traversal allowed. I get no firewall block events. This same code works with windows 2008 server client.

On server (linux ubuntu):

PORT = 12345
import sys, os, time, socket, struct
from socket import gethostname
mc_ttl = 1    
mc_group = '224.7.7.7'

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(0.2)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL,
struct.pack('b', mc_ttl))

d = "my data"
while True:
    sock.sendto(d, (mc_group, PORT))   

on Client (windows 2012 server):

PORT = 12345

import sys, os, time, socket, struct
from socket import gethostname

mc_group = '224.7.7.7'

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', PORT))

mreq = struct.pack("4sl", socket.inet_aton(mc_group), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

while True:
    print sock.recv(10240)

Note the above code works on windows 2008 server. After doing some searching I saw that theres some issues with INADDR_ANY binding to wrong address (and the requisite advice against binding to ''). Inspecting incoming udp traffic on windows client I see the multicast traffic but reciever doesn't get it.

I tried the following after reading this post. Which also did not work.

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
grp = socket.inet_aton(mc_group)
ip = socket.gethostbyname(socket.gethostname())
iface = socket.inet_aton(ip)
mreq = grp + iface

sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
sock.bind((ip, PORT))

Anyone successfully implemented receiver on windows 2012 server?

1

1 Answers

0
votes

I updated the response on the other post to be a bit more explicit. Using socket.gethostbyname() is still getting the default interface, so you'll have to use socket.gethostbyname_ex() to get the extended list then select which interface you want.

Take a look at the difference:

socket.gethostbyname(socket.gethostname())
# "169.254.80.80"
socket.gethostbyname_ex(socket.gethostname()) 
# ("PCName", [], ["169.254.80.80", "192.168.1.10"])

In the above example, we would want to skip over the first 169.254 link-local address and select the desired 192.168.1.10 address. If socket.gethostbyname() was used in the above example, it would have been the link-local (169.254.*) address that would have been selected and your code wouldn't be doing much.

socket.gethostbyname_ex(socket.gethostname())[2][1]
# "192.168.1.10"