質問
誰かがUDPホールパンチの例を挙げてもらえますか?
実際、私はお互いのIPを知っているときに人々がチャットできるチャットプログラムを書きたいと思っています。しかし、両方のマシンはファイアウォールされたルーターの背後にあります。だから、通信するために穴を開ける必要があります。
関数を呼び出すと、穴がパンチされ、将来のコミュニケーションが簡単に移動するようにする機能が欲しいです - それがあまりにも多くを求めることができないなら:)
解決
簡単な答え:確実に行うことはできません。
長い答え:
「ホールパンチ」とは、インバウンドトラフィックを可能にするために、ルーターの自動NATルールのトリガーを指します。 UDPパケットを送信すると、ルーター(通常)は、ソースアドレスとポートを宛先アドレスとポートにマッピングする一時的なルールを作成します。宛先アドレスとポート(および他のポートはありません)から戻ってくるUDPパケットは、元のソースアドレスとポート(および他にはありません)に渡されます。このルールは、数分間の不活動の後にタイムアウトします。
両方のエンドポイントがNATまたはファイアウォールの背後にある場合、これを機能させるには、両方のエンドポイントがほぼ同時に各他の人にパケットを送信する必要があります。これは、双方がそれぞれを知る必要があることを意味します 公衆 IPアドレスとポート番号、および他の手段でこれをお互いに伝える必要があります。
NATの背後にある場合、プログラムが独自のパブリックIPアドレスを直接決定する方法はありません(プライベートアドレスのみが表示されます。 192.168.x.x
)。しかし、あなたは関係する人間がそれぞれのIPアドレスを知っていると仮定しているので、それらの人間は他の住所を入力することができます。
しかし、本当のキャッチは、プログラムがルーターがパブリック側で使用しているポート番号を直接決定する方法もないということです。プログラムはローカルマシンで12345にバインドされる場合がありますが、ルーターはそれをパブリック側のほぼすべてのポートにマッピングできます。 (ローカルネットワーク上の2つのコンピューターがポート12345から送信されると想像してください。明らかにルーターはそれらの1つを別の数にマッピングする必要があります。)ルーターが世界に表示するポート番号を知る方法はありません。
他のヒント
Lidgrenのネットワーキングライブラリには、この機能が組み込まれています。アプリケーションにライブラリを追加した後、NetServerをインスタンス化し、2つのNetClients Connectを使用し、NetServer.introduce()を呼び出します。
Lidgrenへのリンク: https://github.com/lidgren/lidgren-network-gen3