为什么将同一端口上但来自不同组的多播消息组合在一起? [英] Why are multicast messages on the same port but from different groups combined?

查看:130
本文介绍了为什么将同一端口上但来自不同组的多播消息组合在一起?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Ubuntu 14.04服务器上,我有两个进程,每个进程在同一端口上侦听多播消息,但来自不同的组.我本来没想到,但是每个人都能看到他们想要的组和另一个组的流量.

On an Ubuntu 14.04 server I have two processes, each listening for multicast messages on the same port, but from different groups. I would not have expected this, but each sees traffic from both the group they want, and the other group.

据我所知,这是已知的行为(尽管我会称其为问题).我发现了这个SO问题,它提供了一些技术来确定正在从中接收数据的多播组,但是它并没有回答为什么这样的问题首先发生的问题.我本以为基础系统网络代码会过滤掉我未尝试接收的多播组上的消息.

As far as I can tell, this is known behavior (though I would call it a problem). I found this SO question, which provides some techniques for determining the multicast group that data is being received from, but it does not answer the question of why this is even happening in the first place. I would have thought that the underlying system network code would have filtered out messages on multicast groups I am not attempting to receive.

虽然我主要使用C ++,但是我可以提供一些简单的Python代码来演示该问题.在一个终端窗口中,我侦听多播组239.1.1.1的端口12345.在同一服务器上的另一个终端窗口中,我侦听多播组239.2.2.2的端口12345.在第二台计算机上,我在239.1上传输一个多播消息. 1.1:12345,以及239.2.2.2:12345上的其他消息.

While I am mostly working in C++, I can provide some simple Python code to demonstrate the problem. In one terminal window I listen on multicast group 239.1.1.1, port 12345. In another terminal window on the same server I listen to multicast group 239.2.2.2, also port 12345. On a second machine, I transmit one multicast message on 239.1.1.1:12345, and a different message on 239.2.2.2:12345.

在svr3上,发送器:

On svr3, the transmitter:

rcook@svr3:~$ mcast_snd 239.1.1.1 12345 "from 1.1.1"
multicasting from 1.1.1 to 239.1.1.1 port 12345
rcook@svr3:~$ mcast_snd 239.2.2.2 12345 "from 2.2.2"
multicasting from 2.2.2 to 239.2.2.2 port 12345

在svr2的窗口1中,第一个接收者:

On svr2, window 1, the first receiver:

rcook@svr2:~$ mcast_rcv 239.1.1.1 12345
listening for multicast data on 239.1.1.1 port 12345
received 10 bytes: from 1.1.1
received 10 bytes: from 2.2.2

在svr2终端2上,另一个接收器:

On svr2, terminal 2, the other receiver:

rcook@svr2:~$ mcast_rcv 239.2.2.2 12345
listening for multicast data on 239.2.2.2 port 12345
received 10 bytes: from 1.1.1
received 10 bytes: from 2.2.2

如您所见,两个接收方都接收到两条消息.有人可以解释为什么吗?而且,如果有更好的方法将接收者配置为不接收来自其他组的消息,请也共享它.

As you can see, both receivers receive both messages. Can someone explain why this is? And if there is a better way to configure the receivers to not receive messages from other groups, please share that too.

作为参考,这是mcast_rcv的代码:

For reference, here is the code for mcast_rcv:

#!/usr/bin/python

import socket
import struct
import sys

if len(sys.argv) != 3:
    print 'usage:', sys.argv[0], '<multicast group>', '<multicast port>'
    sys.exit(0)

mcast_group = sys.argv[1]
mcast_port = int(sys.argv[2])

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', mcast_port))
mreq = struct.pack('4sl', socket.inet_aton(mcast_group), socket.INADDR_ANY)

sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

print 'listening for multicast data on', mcast_group, 'port', mcast_port

while True:
    msg = sock.recv(10240)
    print 'received', len(msg), 'bytes:', msg

这是mcast_snd的代码:

And here is the code for mcast_snd:

#!/usr/bin/python

import socket
import sys

if len(sys.argv) != 4:
    print 'usage:', sys.argv[0], '<multicast group>', '<multicast port>', '<mess
age>'
    sys.exit(0)

mcast_group = sys.argv[1]
mcast_port = int(sys.argv[2])
message = sys.argv[3]

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)

print 'multicasting', message, 'to', mcast_group, 'port', mcast_port

sock.sendto(message, (mcast_group, mcast_port))

推荐答案

问题已解决.我需要指定要绑定到接收器中的多播组,而不仅仅是端口. 这个SO问题已结束通过在Python代码中将地址保留为''或在我的C ++中将地址保留为INADDR_ANY,我基本上是在告诉操作系统,我希望该端口上的所有消息都不受限制.该系统正像往常一样准确地满足了我的要求.

Problem solved. I need to specify the multicast group to bind to in the receiver, not just the port. This SO question clued me in. By leaving the address as '' in the Python code, or INADDR_ANY in my C++, I am basically telling the OS that I want all messages on that port, regardless of group. The system is giving me exactly what I am asking for, like it always does.

如果在mcast_rcv中用sock.bind((mcast_group, mcast_port))替换行sock.bind(('', mcast_port)),则行为符合我的期望和要求.仅加入多播组(sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq))不足以过滤出该端口上的非组消息.

If I replace the line sock.bind(('', mcast_port)) with sock.bind((mcast_group, mcast_port)) in mcast_rcv, the behavior is as I expect and want. Merely joining the multicast group (sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)) is not enough to filter out non-group messages on that port.

这篇关于为什么将同一端口上但来自不同组的多播消息组合在一起?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆