2009-10-28 143 views
8

同じポートでUDPパケットを送受信できる必要があります。 私はポート5000で聞くことができますが、送信はランダムなハイ・ポートを使用します。 私はVBで書かれているシステムでこれを行い、さまざまなプロトコルの問題をデバッグするためのUDPレスポンダを書く必要があります。同じポートでUDPを送受信する方法は?

http://www.alhem.net(Anders Hedstrom)のOpen Source C++ソケットライブラリを使用していますが、仮想関数UdpSocket :: OnRawData()を使用して受信UDPパケットを受信するためにUdpSocket :: Bind()を使用できましたが、 UdpSocket :: Send()がBind()で選択したポートを使用するようにUdpSocket :: Open()(connect calls)を呼び出すことができませんでした。

Open()関数の移動は役に立ちません。彼らのフォーラムにリクエストを投稿しましたが、これを行うことが可能であると私が読んだことを信じて、おそらくUDPの使い方を理解していないでしょう。

私は何を試してみるべきですか?
--thanks-

+0

同じUdpSocketオブジェクトまたは2つの異なるオブジェクトでBind()とOpen()を呼び出していますか? –

+0

同じインスタンス化されたオブジェクトを使用して、Bind()、次にOpen()、次にSend()を呼び出します。 – cedgriss

答えて

3

双方向通信リンクには常に2つの参加者が含まれます。サーバー側とクライアント側です。

クライアントは、定義されたポートでサーバと通信することを期待しています。そのため、サーバ側ではソケットにbind()する必要があります。

クライアント側では、サーバーへのソケットを開く必要があります。どのソケットが選択されても問題ありません(ただし、空きが必要な場合を除く)。

つまり、クライアント側でソケットを指定しないでください。つまり、ネットワークプロトコルスタックがクライアントにソケットを割り当てます。

+0

システムは、同じポート(異なるIPアドレス)でリッスンする多数のノードで構成されています。システム[A]は、システム[B]にデータグラムを送信する。システム[B]は非同期的に応答し、同じポートを使用してすべて[A]にデータグラムを戻します。 [B]が[A]のポートを識別しても、[A]はそのポートでリッスンしません。私は、診断とテストのためのプロトコルテスト/レスポンダーを開発しており、同じポート#からリスンして送信するサブシステムとして現れる必要があります。私は既存の標準化された実装のすべてである既存のシステムを変更することはできません。 – cedgriss

+0

ダイアグラムを描けますか?物事は簡単になります(少なくとも私にとって)。 – jldupont

8

システムは、同じポート(異なるIP ADDRさん)に聞いてノード の数で構成されています。システム[A]は システム[B]にデータグラムを送信します。システム[B]は非同期に が応答し、同じポートを使用して [A]にデータグラムを戻します。 [B] 識別[A] 'sのポート、[A]、そのポート

に聞いていない された場合でも、私はその文で 『すべて同じポートを使用して』フレーズを理解していません。 AがデータグラムをBに送信すると、BはAのIPとポートをすぐに知るでしょう(あなたのライブラリドキュメントのクイックチェックにより、OnRawDataはstruct sockaddr *saのパラメータを持ちます。もしそれをsockaddr_in*にキャストするとIP:ポートのペア)。そのIP:ポートを使用してデータグラムを送信し、Aがそれらを受信します。 Aはソケット上でlisten()を呼び出さなかったという意味でそのポートで "リッスン"していませんが、Aはそのポートにバインドされているソケットを所有しています(bind() OS)は、データを受信します。

ノード間のすべての通信が固定ポートを通過するようにしたい場合は、これを行うことができます。すべてのデータグラムをあなたの "リスニング"ソケットを通して送信するだけです。すべてのノードが同じポート上で「リッスン」すると、そのノードにバインドされているソケットをすべてのノードが所有していることを意味します。この固定ポートからのデータグラムをAからBに送信する場合は、そのソケットを介して送信する必要があります。私はあなたの送信ソケットでbind()がうまくいかない理由を推測しています - AはソケットXをポートにバインドして、別のソケットを作成して同じポートにバインドしようとします。X、bind()既に取得されています(そして、あなたはエラーをチェックしません:)。そして、OSは1024以上のランダムな空きポートを割り当てます。

注1:UDPソケットのコンテキストでは概念があまり明確ではないので、私はどこでも引用符で "リスニング"を使用します。 bind()を明示的に呼び出したり、データを送信してOSにポートをバインドさせたりすることで、socketを作成してポートにバインドしたら、そこからデータを受け取ることができます。 listen()またはaccept()呼び出しは必要ありません。 UdpSocket :: Open()はconnect()を呼び出しますが、あまり意味がありません。connect()はUDPソケットにはほとんど機能しません。デフォルトのアドレスを設定するだけで使用できるようになります。 sendto()の代わりにsend()を実行し、sendごとにアドレスを指定しないでください。

問題を解決するための希望。


OPのコメントに対処するために編集:私はこのライブラリを一度も使用していませんが、 UdpSocket documentationにはBind()メソッドの4つのオーバーロードがあり、何らかの方法でポートを受け取ります。それらのどれもあなたのために働かない?

+0

優れた答えです。 – aib

+0

お返事ありがとうございます。以前の試みは、あなたのメモが正しいことを示しています。 低レベルのbind()関数に渡される低レベルのstruct sockaddr *アドレスのsin_portフィールドを、 "0"から私が望むソースポートに変更する必要があることを示唆しています( "0"は使用可能送信のためのsrcとしてのポート)。私はコードをステップ実行しており、これにアクセスしてこれを変更するために高度なUpdSocketオブジェクトを使用する方法がまだ見つかりませんでした。私はそれが正しいとは確信しておらず、図書館にこれを行う方法があることを願っています。 – cedgriss

+0

UpdSocket :: Bind()を再チェックしました。すべて受信/受信の設定を参照していますが、4番目のバージョンでは送信ポートを持つSocketAddress&structも使用されています。私はそれをもっと深く見て、それに戻ります。速い応答のために再びありがとう。 – cedgriss

関連する問題