На сервере Ubuntu 14.04 у меня есть два процесса, каждый из которых прослушивает многоадресные сообщения на одном и том же порту, но из разных групп. Я бы не ожидал этого, но каждый видит трафик как из группы, которую они хотят, так и из другой группы.Почему многоадресные сообщения на одном и том же порту, но из разных групп объединены?
Насколько я могу судить, это известное поведение (хотя я бы назвал это проблемой). Я нашел this SO question, в котором приведены некоторые методы определения группы многоадресной передачи, данные которой получены, но она не отвечает на вопрос о том, почему это происходит в первую очередь. Я бы подумал, что базовый системный сетевой код будет отфильтровывать сообщения в многоадресных группах, которые я не пытаюсь получить.
Хотя я в основном работаю на C++, я могу предоставить простой код Python, чтобы продемонстрировать проблему. В одном окне терминала я слушаю многоадресную группу 239.1.1.1, порт 12345. В другом окне терминала на том же сервере слушаю многоадресную группу 239.2.2.2, а также порт 12345. На второй машине я передаю одно многоадресное сообщение на 239.1. 1.1: 12345, а другое сообщение - 239.2.2.2:12345.
На SVR3, передатчик:
[email protected]:~$ mcast_snd 239.1.1.1 12345 "from 1.1.1"
multicasting from 1.1.1 to 239.1.1.1 port 12345
[email protected]:~$ 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, первый приемник:
[email protected]:~$ 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, а другой приемник:
[email protected]:~$ 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
Как вы можете видеть, оба приемника получают оба сообщения. Может кто-нибудь объяснить, почему это так? И если есть лучший способ настроить приемники, чтобы не получать сообщения от других групп, сообщите об этом тоже.
Для справки, вот код для 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:
#!/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))
При поиске дополнительной информации возникли две связанные темы обсуждения.Включая их здесь, они могут быть интересны другим, которые хотят изучить тему и понять различия немного больше: [OpenJDK Discussion] (http://mail.openjdk.java.net/pipermail/net-dev/2013-May/ 006267.html) и [Redhat Discussion] (https://bugzilla.redhat.com/show_bug.cgi?id=231899) – John
@John: вы нашли мое сообщение для redhat :) Существует также другая аналогичная запись в [live555 ] (http://lists.live555.com/pipermail/live-devel/2013-October/017478.html), я добавлю к оригиналу [ответ] (https://stackoverflow.com/a/20919920/3102264) – mpromonet