Отправлять и получать дейтаграммы UDP для локальной многоадресной рассылки IPv6 в Python? - PullRequest
5 голосов
/ 06 июля 2010

Это следующая прямая широковещательная рассылка UDP IPv4 с последующим прослушиванием на всех интерфейсах.

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
sock.bind(("", 1337))
sock.sendto("hello world", ("255.255.255.255", 1337))
while True:
    data, addr = sock.recvfrom(0x100)
    print "received from {0}: {1!r}".format(addr, data)

Я хочу настроить это для отправки и получения IPv4 и IPv6.

Я искал и читаю столько, сколько могу, и считаю, что примерно такой путь мне нужен:

  1. Создание сокета IPv6.
  2. Добавить сокет к локальной группе многоадресной рассылки для ссылки или сайта.
  3. Отправка пакетов UDP на адрес многоадресной рассылки для используемой группы.

Дополнительная информация, которую я имею, заключается в том, что мне может потребоваться привязать несколько интерфейсов и сообщить сокету, используя setsockopt(), что он также должен получать многоадресные пакеты. Наконец, getaddrinfo() можно использовать по всем направлениям, чтобы изящно «вернуться» к IPv4, где IPv6 недоступен.

У меня большая часть этого реализована, но спотыкаюсь в основном на многоадресных частях. Предпочтителен полный пример кода на Python или яркое описание необходимых констант и адресов.

Ответы [ 2 ]

1 голос
/ 13 августа 2010

Вот ссылка на python mcast demo , поддерживает как IPv4, так и IPv6.

0 голосов
/ 26 ноября 2018

В настоящее время я задаю вопрос более здесь , который включает получение многоадресного адреса полученного сообщения, но исходный код отвечает на ваш вопрос!

Для прослушивания:

# Initialise socket for IPv6 datagrams
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)

# Allows address to be reused
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# Binds to all interfaces on the given port
sock.bind(('', 8080))

# Allow messages from this socket to loop back for development
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, True)

# Construct message for joining multicast group
mreq = struct.pack("16s15s".encode('utf-8'), socket.inet_pton(socket.AF_INET6, "ff02::abcd:1"), (chr(0) * 16).encode('utf-8'))
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq)

data, addr = sock.recvfrom(1024)

и отправить:

# Create ipv6 datagram socket
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
# Allow own messages to be sent back (for local testing)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, True)
sock.sendto("hello world".encode('utf-8'), ("ff02::abcd:1", 8080))

Это для python3.6, с python 2.7 Я не думаю, что кодирование необходимо.Также в строке struct.pack я видел варианты «16s15s», такие как «4s», но я не знаю, что это такое и что я работал для меня!

...