2009-07-02 8 views
38

UDPパケットをネットワークサーバーに送信し、応答を受け取るアプリケーションが必要です。サーバーは要求が来たのと同じポート番号に返信します。そのため、まずソケットを任意のUDPポート番号にbind()する必要があります。利用可能なポートにバインドする方法は?

UDPポート番号をハードコードすることは、同じPC上で実行されている他のアプリケーションで使用される可能性があるため、悪い考えです。

利用可能なポートにUDPソケットをバインドする方法はありますか? IMOでは、空きポート番号をすばやく取得する有効な方法である必要があります。 accept()関数。

いいえの場合、バインドしてWSAEADDRINUSE/EADDRINUSEステータスをチェックするのに最適な方法は何ですか:1025から1025までのポートを順番に試してみてください。

+1

accept()は接続ベースのソケットで使用され、データグラムのソケットでは使用されません。 – Beano

+1

おそらく、これは役に立ちます:http://serverfault.com/questions/447044 – yegor256

+0

POSIXでは?また範囲1024+を必要とする:http://stackoverflow.com/questions/913501/how-to-let-kernel-choose-a-port-number-in-the-range-1024-5000-in-tcp-socket- pr –

答えて

34

bindを最初に呼び出しないでsendtoと呼ぶと、ソケットは自動的に(フリーポートに)バインドされます。

+5

正しい答えが@ Remy's(バインドでポート0を使用)でなければならないからです。 – claf

+4

@claf暗黙のバインドもバインドされていますか?私の意見では、どちらの答えも便利です。 – WGH

+0

@WGH:そうです、この動作はWindowsソケット用に書かれています(注:ソケットが開かれ、setsockopt呼び出しが行われ、sendto呼び出しが行われると、Windowsソケットは暗黙のバインド関数呼び出しを行います)。これが他の実装の場合には当てはまらない。さらに暗黙の呼び出しに対する私の意見は、それは悪い習慣であるということです。 – claf

0

データを返信するためにudpソケットを使用しないでください。 sendtoで始まり、recvfrom関数を使用して受信データを読み取っても、データが送信されたアドレスのボーナスとして返信します。

+0

一部のプロトコルでは、最後に使用しているポート番号を気にする必要があります。たとえば、[TFTP](http://tools.ietf.org/html/rfc1350)クライアントは、このサーバーを使用して、同じサーバーからの複数の同時転送を区別します。サーバは同じポートから返信することはできません。各ファイル転送では、別の送信元ポートから送信する必要があります。サーバはあなたが概説したようにクライアントの送信元アドレスとポートに応答します。 – doug65536

+1

私の特定の例では、各転送に新しいソケットを使用すると、盲目的に 'sendto'を実行すると暗黙的にソースポートが選択されますが、実際に' sendto'を実行する前にポート番号を気にする他のプロトコルがあるかもしれません。 。 – doug65536

+0

@ doug65536 thatsは有効な例ですが、元の質問にはなぜその具体的な詳細が含まれていませんでした。 – Jonke

168

もう1つのオプションは、ポート0をbind()に指定することです。これにより、ランダムポートにバインドしながら、特定のIPアドレス(複数のがインストールされている場合)にバインドできます。どのポートが選択されたかを知る必要がある場合は、バインディングが実行された後にgetsockname()を使用できます。

+18

ポート0へのバインディングは、OSが割り当てたランダムポートにバインドする公式に文書化された方法です。 –

+0

ここに記載されていますか?私はこれが間違っていると言っているわけではありません、私は権威ある声明を見たいと思います。 –

+8

['bind()'](http://msdn.microsoft.com/en-us/library/windows/desktop/ms737550.aspx)ドキュメントにあります: "ポートがゼロとして指定されている場合、サービスプロバイダは動的クライアントポート範囲からアプリケーションに一意のポートを割り当てます。Windows Vista以降では、動的クライアントポート範囲は49152〜65535の値です。これはWindows Server 2003以前のバージョンからの変更です。動的クライアントポート範囲1025と5000の間の値でした...アプリケーションはソケットに割り当てられたアドレスとポートを知るためにbindを呼び出すとgetsocknameを使用することができます。 –

関連する問題