回答:
ブロードキャストにより、クライアントはネットワーク上の全員にメッセージを送信し、すべてのサーバーが応答します。マルチキャストでは、マルチキャストグループアドレスを定義し、すべてのサーバーがそれにサブスクライブします。次にクライアントはメッセージをグループに送信し、サブスクライブしたサーバーはメッセージを受信して応答します。
マルチキャストは、ゲームクライアントがサーバーの(潜在的な)グループに送信する場合など、1つの送信者が受信者のグループに送信する場合に使用します。マルチキャストアドレスは、システムがそれらを異なる方法で処理することがわかっている特別なアドレスです。受信者は特定のグループに送信されたメッセージを受信することをシステムに通知し、送信者はグループアドレスにメッセージを送信します。LANでは、これでうまくいきます。LAN間では、ほとんどのネットワークに実装されていないマルチキャストルーティングが必要です。しかし、ブロードキャストはLAN全体で機能しません。
マルチキャストを使用すると、メッセージを取得することに関心があるネットワーク上のシステムのみが確実にメッセージを受信します。
これをどのように実装するかは、プログラミング言語などによって異なります。
IPv6マルチキャストアドレスの構造は次のとおりです。
ff
。つまり、アドレスの最初の2文字はになります。0
は、永続的に割り当てられるマルチキャストアドレスを示すaになります。2
リンクローカル(LAN)スコープの値を使用します。つまり、これは、で始まるアドレスを使用することを意味しますff02:
。
マルチキャストアドレスはIANAによって割り当てられます。RFC3307はそれを行う方法を定義します(基準はエキスパートレビューであるため、自分がやっていることやそのようなことについてRFCを記述する必要はありません)。この回答では、マルチキャストアドレスを使用しますff02::db8:aa:bb
では、ドキュメント用に予約されたブロックにあるします。
マルチキャストを使用するためにrootアクセスを持っている必要はありません。次のPython3.3の例は、通常のユーザーアカウントで実行できます。
サーバー(マルチキャストアドレスをリッスン):
#!/usr/bin/env python3.3
import socket
import struct
if_idx = socket.if_nametoindex('en0')
addr = 'ff02::db8:aa:bb'
port = 42424
group = socket.inet_pton(socket.AF_INET6, addr) + struct.pack("I", if_idx)
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, group)
sock.bind(('::', port))
while True:
msg, sender = sock.recvfrom(1024)
print('Received "%s" from "%s"' % (str(msg, 'UTF-8'), sender))
sock.sendto(bytes('Received %d bytes from you' % len(msg), 'UTF-8'), sender)
そして、クライアント(マルチキャストグループに送信し、応答をリッスンします):
#!/usr/bin/env python3.3
import socket
if_idx = socket.if_nametoindex('en0')
addr = 'ff02::db8:aa:bb'
port = 42424
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, if_idx)
sock.sendto(bytes('Hello there!', 'UTF-8'), (addr, port))
while True:
# You probably wait a certain time for replies, not indefinitely like this example
msg, sender = sock.recvfrom(1024)
print('Received "%s" from "%s"' % (str(msg, 'UTF-8'), sender))
古いバージョンにはがないため、Python 3.3を使用しましたがsocket.if_nametoindex
、それ以外はPython 2でも機能するはずです。
PS:別の回答で提案されているように、サービス検出に既存のライブラリまたはフレームワークを使用することは良い考えです。これは内部でマルチキャストを使用しますが、独自のプロトコルを設計および実装する必要がなくなります。
サービス検出のためのプロトコルがありますIPv4とIPv6のどちらを使用していても、最新のアプリケーションがブロードキャストまたはホームスパンマルチキャストソリューションの代わりに使用する必要のあるます。
AppleがmDNS / DNS-SDをプッシュし、MicrosoftがUPnPをプッシュます。どちらもシンプルなサービスディスカバリで同じ目標を達成しますが、UPnPは多くの追加機能を提供します。
複数のプラットフォーム用のこれらのAPIの両方に無料で利用できるライブラリがあります。関連するOSにはネイティブサポートが含まれます。Linuxは、ほとんどのディストリビューションにデフォルトでインストールされる準標準システムコンポーネントを介してサポートを提供します。
UPnPはファイアウォールの構成にも使用できるため、インターネットでのプレイを計画しているゲームにはUPnPファイアウォール制御に依存したり要求したりすることはできませんが、互換性のあるルーターを使用したり、パラノイアから外れた機能。