IPv6テクノロジーを使用してLANネットワークでゲームサーバーを見つける方法は?


8

IPv4時代に戻って、ブロードキャストパケットを単に使用した人々は、この回答で説明されているように、ネットワークに利用可能なサーバーがあるかどうかを確認します。しかし、IPv6プロトコルでは、ブロードキャストのサポートを廃止しました。利用可能なマルチキャストサポートはまだありますが、どのように使用できますか?

回答:


7

ブロードキャストにより、クライアントはネットワーク上の全員にメッセージを送信し、すべてのサーバーが応答します。マルチキャストでは、マルチキャストグループアドレスを定義し、すべてのサーバーがそれにサブスクライブします。次にクライアントはメッセージをグループに送信し、サブスクライブしたサーバーはメッセージを受信して​​応答します。

マルチキャストは、ゲームクライアントがサーバーの(潜在的な)グループに送信する場合など、1つの送信者が受信者のグループに送信する場合に使用します。マルチキャストアドレスは、システムがそれらを異なる方法で処理することがわかっている特別なアドレスです。受信者は特定のグループに送信されたメッセージを受信することをシステムに通知し、送信者はグループアドレスにメッセージを送信します。LANでは、これでうまくいきます。LAN間では、ほとんどのネットワークに実装されていないマルチキャストルーティングが必要です。しかし、ブロードキャストはLAN全体で機能しません。

マルチキャストを使用すると、メッセージを取得することに関心があるネットワーク上のシステムのみが確実にメッセージを受信します。

これをどのように実装するかは、プログラミング言語などによって異なります。

IPv6マルチキャストアドレスの構造は次のとおりです。

  • アドレスの最初の8ビットは常に1に設定されていますff。つまり、アドレスの最初の2文字はになります。
  • アドレスの3番目の文字(ビット9〜12)はフラグを指定します。あなたの場合、あなたはおそらくあなたのアプリケーションのために固定マルチキャストアドレスを望みます。その場合、3番目の文字0は、永続的に割り当てられるマルチキャストアドレスを示すaになります。
  • 4番目の文字(ビット13から16)は、アドレスのスコープを決定します。おそらく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:別の回答で提案されているように、サービス検出に既存のライブラリまたはフレームワークを使用することは良い考えです。これは内部でマルチキャストを使用しますが、独自のプロトコルを設計および実装する必要がなくなります。


グループを作成/参加するには、管理者権限が必要ですか?そして、このグループのことはどのように機能するのですか?グループアドレスを作成/参加するときに、グループアドレスを選択するのですか?
Ali1S232

回答をさらに詳しく説明します
Sander Steffann

この答えはおそらく技術的に正しいですが、マルチキャストがどのように機能するかについての説明が少し欠けています。マルチキャストソケットを作成でき、ネットワーク内の誰もがこのソケットの場所を知っていることを正しく理解していますか?
API-Beast

また、そうであれば、どのソケットがローカルネットワークにあり、どのソケットがインターネットのように外部にあるかをどのように区別していますか。
API-Beast

拡大された答え
サンダー・ステファン

4

サービス検出のためのプロトコルがありますIPv4とIPv6のどちらを使用していても、最新のアプリケーションがブロードキャストまたはホームスパンマルチキャストソリューションの代わりに使用する必要のあるます。

AppleがmDNS / DNS-SDをプッシュし、MicrosoftがUPnPをプッシュます。どちらもシンプルなサービスディスカバリで同じ目標を達成しますが、UPnPは多くの追加機能を提供します。

複数のプラットフォーム用のこれらのAPIの両方に無料で利用できるライブラリがあります。関連するOSにはネイティブサポートが含まれます。Linuxは、ほとんどのディストリビューションにデフォルトでインストールされる準標準システムコンポーネントを介してサポートを提供します。

UPnPはファイアウォールの構成にも使用できるため、インターネットでのプレイを計画しているゲームにはUPnPファイアウォール制御に依存したり要求したりすることはできませんが、互換性のあるルーターを使用したり、パラノイアから外れた機能。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.