2009-06-30 11 views
1

長寿命の接続を持つUDPサーバーアーキテクチャでは、受信UDPトラフィックをすべて受信するソケットが1つあり、 connect()を使用してリモートアドレスを設定すると、接続ごとに別々のソケットを作成します。私の質問は、TCPに対してaccept()と同じように原子的に行うことが可能かどうかです。UDP用のエミュレートaccept()(デマルチプレクスされたUDPソケットの設定におけるタイミングの問題)

別のソケットを作成してconnect()を使用する理由は、これによって複数のスレッドにパケット処理を分散しやすくし、必要なデータ構造にソケットを直接関連付けることが容易になるからです処理のために。 ネットワークスタックのデマルチプレクスロジックは、入力パケットを最も特定のソケットにルーティングします。

今、私の質問は次のようにUDPのために)1は、(受け入れるエミュレートしたいときに何が起こるか基本的には次のとおりです。

  1. 使用(選択)UDPサーバソケットを含み、FD-セットを持ちます。

  2. 次に、UDPサーバーソケットからパケットを読み取ります。

  3. はその後、その後

  4. が、私は両方のソケットが含まFD-セットでselect()を呼び出してリモートアドレスに()編を接続され、新たなUDPソケットを作成します。

  5. 返されるものは何ですか?パケットは、1と3

    はUDPサーバソケットにパケットを逆多重化されるか、またはそれは3で作成した複数の特定のソケットに分波されますどこかの間でOSに到着したことを考えると

つまり、どの時点でデマルチプレクスが行われますか?パケットが到着したとき、またはポイント4に到着したときに「あたかもあたかも」起こっていなければならないか?

上記のような場合にはフォローアップの質問があります:これを行うにはどうすればよいですか?

+0

もう一方の端に接続された新しいUDPソケットを作成しても、同じサーバー側のポートを維持できますか? 通常は、サーバー側の別のポートにUDPソケットを作成し、最初の要求にのみ「サーバーソケット」を使用し、さらに2つの異なるポートでピアとの通信をさらに行います。 または、サーバー上に1つのソケットだけを使用して、接続する気にしないでください。ピアアドレスをメモするだけです。とにかくUPDはコネクションレスです。 – nos

答えて

0

これは機能しません。
2つの簡単なオプションがあります。

  1. 「ルート」スレッドUDPソケット上で待機し、ソースに基づいて正しいスレッドに受信したパケットを「ディスパッチ」を持っているマルチスレッドプログラムを作成します。これは、ソースごとに処理を分離したいからです。

    • ソースが固定ポートで着信接続を受け入れるようにプロトコルを拡張してから、プロトコル通信を続行します。この場合、(あなたが選択した)標準UDPポートでソースリクエストを許可すると、新しいUDPソケットからソースのUDPポートにエンドが応答します。このようにして、各ソースの既知のUDPポートに向かって右から新しいUDPパスを開始しました。そうすれば、あなたはあなたの最後に異なるUDPソケットを持っています。
+0

これはなぜ機能しませんか?最も具体的なソケットにデマルチプレクスするOSの例については、 http://lxr.linux.no/linux-bk+v2.6.5/net/ipv4/udp.c#L222 を参照してください。 私の提案したソリューションの問題は、ソリューション1が拡張されず、ソリューション2によって生成されたパケットが特定のNATの背後にあるクライアントに届かないということです。 –

+0

[OK]を、私はあなたがソケット層の下でコーディングする意思があるとは思わなかった。 – nik

0

私は、この議論は2009年からであることがわかり、それは私が検索したときにポップアップ続けているので、私は私のアプローチを共有しなければならないと思いました。私は両方のフィードバックを得るために、私は問題の著者がどのように問題を解決したかという点に関心があるからです。

私がエミュレートする方法は、nikの答えで1番と2番の組み合わせでした。私は、特定のソケットをリッスンするルートスレッドを持っています。わかりやすくするためにTCPを使用することにしましたが、このソケットをUDPに変更することはあまり難しくありません。クライアントがUDPを使用して自分のサーバーに「接続」したいときは、最初にTCPソケットに接続し、新しい接続を要求します。

次に、ルートスレッドはUDPソケットを作成して、ローカルインターフェイスにバインドし、接続してデータ構造を設定します。このファイル記述子は、接続を担当するスレッドに渡されます。新しいUDPソケットのIP /ポート情報がクライアントに戻され、新しいUDPソケットが作成され、提供されたIP /ポートにデータが送信されます。

このアプローチは、私の使用にはうまくいきますが、フローを設定するための追加の手順でオーバーヘッドが発生します。場合によっては、このオーバーヘッドが受け入れられないことがあります。

関連する問題