如何在localhos上使用多播限制流量

2024-03-28 19:51:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用本地主机上的多播UDP来实现在一台机器上运行的松散的协作程序集合。以下代码在MacOSX、Windows和linux上运行良好。该缺陷是代码也将在本地主机网络之外接收UDP数据包。例如,sendSock.sendto(pkt, ('192.168.0.25', 1600))在从网络上的另一个框发送时由我的测试计算机接收。

import platform, time, socket, select

addr = ("239.255.2.9", 1600)

sendSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sendSock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 24)
sendSock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, 
    socket.inet_aton("127.0.0.1"))

recvSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
recvSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
if hasattr(socket, 'SO_REUSEPORT'):
    recvSock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, True)

recvSock.bind(("0.0.0.0", addr[1]))
status = recvSock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, 
    socket.inet_aton(addr[0]) + socket.inet_aton("127.0.0.1"));

while 1:
    pkt = "Hello host: {1} time: {0}".format(time.ctime(), platform.node())
    print "SEND to: {0} data: {1}".format(addr, pkt)
    r = sendSock.sendto(pkt, addr)

    while select.select([recvSock], [], [], 0)[0]:
        data, fromAddr = recvSock.recvfrom(1024)
        print "RECV from: {0} data: {1}".format(fromAddr, data)

    time.sleep(2)

我试图recvSock.bind(("127.0.0.1", addr[1])),但这会阻止套接字接收任何多播通信。是否有适当的方法将recvSock配置为只接受来自127/24网络的多播数据包,或者需要测试每个接收数据包的地址?


Tags: ip网络datatimesocket数据包selectaddr
3条回答

如果主机支持IPv6,则可以使用多播地址的作用域组件(这是多播前缀FF0x:中的“x”)通过指定1的作用域(例如,仅在本地主机上使用IPv6多播地址FF01::107作为“名称服务服务器”),隐式将传入和出站数据包限制到本地主机。不幸的是,IPv4多播机制没有显式作用域,定义了管理作用域IPv4多播范围的rfc2365(http://tools.ietf.org/html/rfc2365)没有定义节点本地作用域地址,而只定义了链路本地作用域范围。

不幸的是,多播IP没有任何这样的“按子网过滤”功能——所以,除非你想用IPTables(在Linux上)或等效的系统/网络“防火墙”SW/HW来尝试将你不喜欢的每个多播数据包“扔到地板上”,我认为您必须在应用程序级别进行测试(例如,在您的内部循环中对fromAddr进行测试)。来自其他主机的IP流量是否会降低您的性能。。。?

与其他答案相反,IPv4支持基于TTL的多播作用域,如下所示:

0: node-local (not forwarded outside the current host)
1: link-local (not forwarded outside the current subnet)
< 32: site-local
< 64: region-local
< 128: continent-local
< 255: global

(它还支持Administratively Scoped Multicast。)

资料来源:W.R.Stevens,Unix网络编程,2nd版本,第一卷,第19.2节,更正为匹配RFC 2365

相关问题 更多 >