2009-11-22 26 views
6

私のサーバに複数のIPアドレスが割り当てられていて、そのうちのいくつか(またはすべて)を聞きたいのですが、どうすればいいですか?複数のIPアドレスをリッスンする方法は?

各IPアドレスに新しいソケットを作成してバインドする必要がありますか? 1つのソケットに複数のIPアドレスをバインドできますか? IPAddress.AnyはすべてのIPアドレスでリッスンしますか? MSDNライブラリはこの点について非常に不明です。

答えて

13

複数のエンドポイントに1つのソケットをバインドすることはできません。指定されたソケットに対してBind()を呼び出すと、SocketException(無効な引数エラー)が発生します。

他の人は言ったように、IPAddress.Anyを使ってローカルマシンのIPv4アドレスを聞くことができます。ただし、使用可能なIPアドレスのサブセットのみをリッスンする場合は、別のソケットを作成する必要があります。

+0

さて、決定的な答えをありがとう。 –

+5

いいえ、単純にIP v6アドレスをカウントすると、IPAddress.AnyはSocketオブジェクトをすべてのIPアドレスにバインドしません。 正しい方法は、2つのSocketオブジェクトを作成することです。次に、IPAddress.Anyにバインドし、もう1つはIPAddress.IPv6Anyにバインドします。 –

+0

良い点。私のプロジェクトは依然としてIPv4だけなので、私の答えを書いたときにIPv6は考慮されていませんでした。 –

2

はい、IPAddress.Anyはすべてのインターフェイスでリッスンします。

http://msdn.microsoft.com/en-us/library/system.net.ipaddress.any.aspx

+0

これは役に立ちます(Bindメソッドは、フレームワークがリッスンするアドレスを選択すると言っていますが、かなり曖昧です)。しかし、コンピュータに割り当てられた10のIPアドレスのうち5つだけを聞きたいのですが?それに5つのソケットが必要ですか?または別のエンドポイントでBind()を複数回呼び出すことはできますか? –

+0

はい、AnyまたはIPv6Anyにバインドしない限り、アドレスごとに1つです。 –

4

技術的には、サーバーは、それに割り当てられたIPアドレスを持っていることはありません。

代わりに、個々のネットワークインターフェイスにIPアドレスを割り当てることができます。通常、各NICは1つのIPアドレスを取得しますが、これは単なる最も一般的なケースです。

選択したポートで着信接続をリスンするインターフェイスを制御する場合は、それぞれのインターフェイスに個別のソケットを作成する必要があります。

+1

はい、私はインターフェイスにIPアドレスを割り当てているが、.NETはそれを隠してエンドポイントにバインドするだけであることに気付いています。 IPAddress.Anyを使用して複数のインターフェイスをリッスンすることはできますが、特定のソケットを聴くには複数のソケットが必要なのはなぜか分かりません。 –

+1

私はフレームワークのデザイナーが「共通のケースを容易に達成してみましょう」と考えて、便利なショートカットを提供していると思います。 – Bevan

+0

AnyおよびIPv6Anyはショートカットと見なすことができます。しかし、あなたが望むすべてのショートカットを提供するためのフレームワークを求めることはできませんでした。私は完全にBevanに同意する。 フレームワークをもっと使いこなし、自分でデザインを始めたら、常に選択が難しいことがわかります。 –

2

MSDNライブラリはIPAddress.Anyに関してcontradcitoryのようです。バインドドキュメント

http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.bind.aspx

は、「最適な」アドレスが選択されていることを述べているが、IPAddress.Anyドキュメント

http://msdn.microsoft.com/en-us/library/system.net.ipaddress.any.aspx

は、この定数とソケットが上の活動のために耳を傾けなければならないことを言いますすべてのインターフェイス。

しかし、正しいIPAddress.Anyドキュメントだと言われます。

(私はコメントを残すのに十分な担当者がいないため、これを回答として追加します)。

3

私はそれに取り組んだ、IPAddress.Anyは適切な方法ではない、適切なIPアドレスをバインドします。私の場合、2枚のNICがあり、問題を解決することはできませんでした。追加したとき

System.Net.IPAddress ipAddress = IPAddress.Parse("xxx.xxx.xxx.xxx"); 
listener = new TcpListener(ipAddress, portNum); 

正常に機能しました。

3

あなたはこのコードを使用して、すべてのIPv4アドレスとIPv6アドレスをリッスンしたい場合:

var listener = new TcpListener(IPAddress.IPv6Any, port); 
listener.Server.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false); 

IPv6Any IPv6スタック上でリッスンするようにWindowsに指示します。 socketオプションをfalseに設定すると、WindowsはIPv6スタックに制限されず、IPv4スタックをリッスンするようになります。デフォルトでは、明示的に指定されたスタックだけをリッスンします。

+0

うわー、それはかなり...うーん..明白ではありません;)これは、複数のIPを選択的に聞く方法を証明していないと思います。 –

+0

これは大部分の人にとって重要ではないかもしれませんが、これは.NET 4以降でのみサポートされています。 – eAi

関連する問題