98

PythonでUDPマルチキャストをどのように送受信しますか? そうするための標準ライブラリはありますか?

4

9 に答える 9

112

これは私のために働く:

受け取る

import socket
import struct

MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007
IS_ALL_GROUPS = True

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if IS_ALL_GROUPS:
    # on this port, receives ALL multicast groups
    sock.bind(('', MCAST_PORT))
else:
    # on this port, listen ONLY to MCAST_GRP
    sock.bind((MCAST_GRP, MCAST_PORT))
mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)

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

while True:
  # For Python 3, change next line to "print(sock.recv(10240))"
  print sock.recv(10240)

送信

import socket

MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007
# regarding socket.IP_MULTICAST_TTL
# ---------------------------------
# for all packets sent, after two hops on the network the packet will not 
# be re-sent/broadcast (see https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html)
MULTICAST_TTL = 2

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

# For Python 3, change next line to 'sock.sendto(b"robot", ...' to avoid the
# "bytes-like object is required" msg (https://stackoverflow.com/a/42612820)
sock.sendto("robot", (MCAST_GRP, MCAST_PORT))

これは、動作しなかったhttp://wiki.python.org/moin/UdpCommunicationの例に基づいています。

私のシステムは... Linux 2.6.31-15-generic #50-Ubuntu SMP Tue Nov 10 14:54:29 UTC 2009 i686 GNU/Linux Python 2.6.4

于 2009-11-25T03:03:07.967 に答える
20

マルチキャスト グループにブロードキャストするマルチキャスト送信者:

#!/usr/bin/env python

import socket
import struct

def main():
  MCAST_GRP = '224.1.1.1'
  MCAST_PORT = 5007
  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)
  sock.sendto('Hello World!', (MCAST_GRP, MCAST_PORT))

if __name__ == '__main__':
  main()

マルチキャスト グループから読み取り、16 進データをコンソールに出力するマルチキャスト レシーバー:

#!/usr/bin/env python

import socket
import binascii

def main():
  MCAST_GRP = '224.1.1.1' 
  MCAST_PORT = 5007
  sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
  try:
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  except AttributeError:
    pass
  sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32) 
  sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)

  sock.bind((MCAST_GRP, MCAST_PORT))
  host = socket.gethostbyname(socket.gethostname())
  sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(host))
  sock.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, 
                   socket.inet_aton(MCAST_GRP) + socket.inet_aton(host))

  while 1:
    try:
      data, addr = sock.recvfrom(1024)
    except socket.error, e:
      print 'Expection'
      hexdata = binascii.hexlify(data)
      print 'Data = %s' % hexdata

if __name__ == '__main__':
  main()
于 2009-07-20T03:40:37.433 に答える
14

より良い使用:

sock.bind((MCAST_GRP, MCAST_PORT))

それ以外の:

sock.bind(('', MCAST_PORT))

同じポートで複数のマルチキャスト グループをリッスンする場合は、すべてのリスナーですべてのメッセージを取得するためです。

于 2011-10-06T13:55:47.557 に答える
2

py-multicastを見てください。ネットワークモジュールは、インターフェイスがマルチキャストをサポートしているかどうかを確認できます(少なくともLinuxでは)。

import multicast
from multicast import network

receiver = multicast.MulticastUDPReceiver ("eth0", "238.0.0.1", 1234 )
data = receiver.read()
receiver.close()

config = network.ifconfig()
print config['eth0'].addresses
# ['10.0.0.1']
print config['eth0'].multicast
#True - eth0 supports multicast
print config['eth0'].up
#True - eth0 is up

おそらく、IGMPが表示されないという問題は、マルチキャストをサポートしていないインターフェイスが原因でしたか?

于 2010-09-23T18:16:13.477 に答える
0

IP_MULTICAST_TTLクライアント コード (tolomea から) を Solaris で動作させるには、ソケット オプションの ttl 値を unsigned char として渡す必要があります。そうしないと、エラーが発生します。これは、Solaris 10および11で機能しました。

import socket
import struct

MCAST_GRP = '224.1.1.1'
MCAST_PORT = 5007
ttl = struct.pack('B', 2)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
sock.sendto("robot", (MCAST_GRP, MCAST_PORT))
于 2014-01-24T12:12:32.773 に答える
0

この例は、あいまいな理由でうまくいきません。

曖昧ではなく、単純なルーティングです。

OpenBSD の場合

route add -inet 224.0.0.0/4 224.0.0.1

Linux の dev へのルートを設定できます

route add -net 224.0.0.0 netmask 240.0.0.0 dev wlp2s0

Linux ですべてのマルチキャスト トラフィックを 1 つのインターフェイスに強制する

   ifconfig wlp2s0 allmulti

tcpdump はとてもシンプルです

tcpdump -n multicast

コードには次のものがあります。

while True:
  # For Python 3, change next line to "print(sock.recv(10240))"

なぜ10240 ?

マルチキャスト パケットのサイズは1316 バイトにする必要があります

于 2020-12-03T12:03:04.190 に答える
-1

トロメアの答えは私にとってはうまくいきました。私もそれをsocketserver.UDPServerにハッキングしました:

class ThreadedMulticastServer(socketserver.ThreadingMixIn, socketserver.UDPServer):
    def __init__(self, *args):
        super().__init__(*args)
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.bind((MCAST_GRP, MCAST_PORT))
        mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
        self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
于 2013-08-08T15:10:04.640 に答える