軽量のLANピア発見のためのソリューション?


9

純粋にクロスプラットフォームプログラミング用のライブラリを構築しました。それで作られた私のゲームは、Android、PC、Linux、Macなどでうまく動作します。

ネットワーキング機能はENETライブラリによって提供されるため、アプリ間のすべての通信はTCPまたはUDP互換ではなく、カスタムプロトコルのみで行われ、最終的にはUDPに基づいたものでさえ困難です。

私がENETでやりたいことができるとは思えないので、ここで助けを求めます!

Androidフォン、ラップトップ、PCで同じゲームを実行しているとしましょう。Wifiホットスポット(?)でも家庭用ルーターでも、それらはすべて同じwifiネットワーク内にあるため、LAN内にあります。

ネットワーク内の他の2つを検出するには、これら3つのピアがそれぞれ必要です。これは、LANネットワークで生きているアプリのIPを見つけて、それらの間でマルチプレイヤーゲームをホストできるようにすることのみを目的としています。

これを行うには、UDPブロードキャスト、応答待機の1つの効果的な方法しか考えられませんが、それが解決策である場合は、実装の唯一の目的であるため、小さなものが必要です。

他の方法は、LANアドレスのサブ範囲内のすべてのIPに接続しようとすることですが、これはOSが私と一緒にいるとは思いません:p


2
いくつかのUDPブロードキャストが適切な方法だと思いますが、それに対するあなたの異論が理解できません。または、ENETがブロードキャストをサポートしていないのでしょうか。
ロイT.

正確には、それは、それだけですでに知られているピアにブロードキャストすることができていません...
グリムショー

stackoverflow.com/questions/683624/…これは回答に影響しますか?
Grimshaw

回答:


5

多くの人が言っているように、解決策はUDPブロードキャストを使用することですが、関係する実装の詳細はたくさんあります。最近同じ問題に遭遇し、解決策を検討したブログ投稿と、LANチャットサーバー/クライアントの形式のサンプルプロジェクトを作成しました。ここでそれらを要約しますが、詳細と実際のコードについては、それらをチェックアウトする必要があります。

ENetの作成者であるLee Salzmanの説明に基づいて、次のように動作します。

  • ゲームサーバーはENetホストとして1つのソケットで実行されます
  • サーバーは、通常のUDPソケット(つまり、ENetホストではない)として、既知の「リッスン」ポートにもバインドします
  • クライアントはUDPブロードキャストメッセージ(つまり、IP 255.255.255.255)をそのリスンポートに送信し、応答を待ちます。
  • LAN内のすべてのサーバーは、その「スキャン」メッセージを受信して​​応答します。理想的には、ゲームサーバー(ENetホスト)が実行されているポートで応答できます。そうすれば、ゲームサーバーを固定ポートで実行する必要がなくなります)
  • クライアントはいくつかの応答を受け取った後、どのサーバーが存在するかを認識します。次に、それらの1つを選択して、通常のENetピアとして接続します。この時点で、クライアントはUDP「スキャナー」ソケットを必要としません。

良いニュースは、ENetがソケットを使用するためのラッパー関数を提供するため、ENetですべてを実行できることです。悪いニュースは、ラッパーが非常に薄いことです。何ができるかなど、ソケットプログラミングについて知っておく必要がありますselect()。そのため、コードをコピーして貼り付けて時間を大幅に節約できるように、ブログ投稿サンプルプロジェクトを確認することをお勧めします。

独自の実装を選択した場合の注意点と落とし穴は次のとおりです。

  • リスナー/スキャナー UDPである必要があるので、enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM)(またはSOCK_DGRAMプレーンソケットプログラミングを使用して)リスナーを作成する必要があります。
  • サーバー「リスナー」の場合、複数のサーバーが同じIPで実行できるようにenet_socket_set_option(socket, ENET_SOCKOPT_REUSEADDR, 1)(またはSO_REUSEADDR)を使用してポートアドレスを再利用できるようにします
  • クライアント「スキャナー」の場合、UDPソケットでenet_socket_set_option(scanner, ENET_SOCKOPT_BROADCAST, 1)(またはSO_BROADCAST)を使用してブロードキャストを有効にする必要があります。そうしないと、ブロードキャストアドレスに送信できません。これは安全機能のみであり、誤ってネットワークをフラッディングすることを防ぎます。

残念ながら、これは「軽量」なソリューションではありません。サンプルプロジェクトは、全体で数百のLOCで稼働します。これがENetのユーティリティライブラリにパッケージ化されていると便利ですが、ゲームサーバーの場合は、サーバー応答でさらにゲーム固有の情報を送信して、次のような便利なものにしたいと思うことがよくあります。

  • ゲームの種類(「協力」、「デスマッチ」など)
  • サーバーが実行している「マップ」、「レベル」、または「キャンペーン」
  • サーバーのプレーヤーと最大プレーヤーの数
  • 接続するかどうかのクライアントの決定に影響を与えるその他のゲーム固有の情報。ゲームの「サーバーブラウザー」と、それらが表示する情報の種類について考えてください。

これはまさに私が考えていたものです。放送は進むべき道です。
Lolums 2016年

3

ライブラリを離れたくない場合は、ブルートフォースを使用して、可能なアドレスのそれぞれに接続を試みることができます。ほとんどのホームLANはクラスCネットワーク(/ 24)であり、IPアドレスの最初の24ビットは同じで、最後の8ビットは異なります。したがって、IPアドレスは255個しかありません。

しかし、それでも、UDPブロードキャストを実行するほうが、よりクリーンな代替手段になります。UDPパケットを255.255.255.255に送信するだけで、同じルーターの背後にあるすべてのクライアントが受信します。次に、パケットの送信元IPおよび送信元ポートに応答を送信して、それらが存在することを送信者に通知します。


2
してくださいしてくださいしてくださいしてください してくださいブルートフォースをしないでください。
Trevor Powell

@TrevorPowell ...だから...?
フィリップ2013年

2
それは間違った解決策だからです。大学(class-cネットワークを使用しない)や企業(通常、class-cネットワークを使用しない)では機能せず、どちらのITスタッフも、すべてのプレイヤーがブルートフォースは、「更新」ボタンをクリックするたびに、ネットワーク内のすべてのIPアドレスにメッセージを送信しようとします。これは問題の悪い解決策です。数学サーバーなしで潜在的なピアを特定するというこの質問は、まさにブロードキャストの目的です。ブロードキャストを使用します。それはあらゆる点で優れています。:)
Trevor Powell

1

あなたは見て持つことができDNS-SD / Zeroconfを / Avahiは / Bonjourの/ のmDNSを。これは、AppleがプリンタやiTunesフォルダなどを共有するために使用するものですが、他の場所でも採用されています。AvahiはLinuxが使用するオープンソースバージョンであり(Linuxのみかどうかは不明)、全体の移植性は不明です(ほとんどのプラットフォームには実装があります)。

そうは言っても、UDPブロードキャストを行う方がおそらく簡単です。

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