Python在Windows 2012服务器中接收多播失败

1 投票
1 回答
574 浏览
提问于 2025-04-18 05:11

在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"

撰写回答