Python在Windows 2012服务器中接收多播失败
在Windows 2012服务器上运行的Python多播接收器没有收到UDP流量。我检查了一下流量,发现UDP流量确实在传输。我为多播组设置了一个防火墙的UDP规则,并允许边缘穿越。防火墙没有阻止任何事件。相同的代码在Windows 2008服务器客户端上是可以正常工作的。
在服务器(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))
在客户端(Windows 2012服务器)上:
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)
注意,上面的代码在Windows 2008服务器上是可以工作的。经过一些搜索,我发现INADDR_ANY绑定到错误地址的问题(还有关于不要绑定到''的建议)。在Windows客户端上检查进入的UDP流量时,我看到多播流量,但接收器没有收到。
我在阅读了这篇帖子后尝试了以下方法,但也没有成功。
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))
有没有人在Windows 2012服务器上成功实现接收器?
1 个回答
0
我在另一个帖子上更新了回复,让内容更清楚一些。使用 socket.gethostbyname()
仍然会得到默认的网络接口,所以你需要使用 socket.gethostbyname_ex()
来获取更详细的列表,然后选择你想要的网络接口。
看看它们之间的区别:
socket.gethostbyname(socket.gethostname())
# "169.254.80.80"
socket.gethostbyname_ex(socket.gethostname())
# ("PCName", [], ["169.254.80.80", "192.168.1.10"])
在上面的例子中,我们想跳过第一个 169.254 的链接本地地址,选择我们想要的 192.168.1.10 地址。如果在上面的例子中使用了 socket.gethostbyname()
,那么选中的将是链接本地地址(169.254.*),这样你的代码就不会有什么用处了。
socket.gethostbyname_ex(socket.gethostname())[2][1]
# "192.168.1.10"