2009-11-22 60 views
6

如果我的服务器有多个分配给它的IP地址,我想倾听他们中的一些(或全部)IP地址,我该怎么做?如何在多个IP地址上收听?

是否需要为每个IP地址创建一个新的套接字并绑定它?我可以将多个IP地址绑定到一个套接字上吗? IPAddress.Any是否侦听所有IP地址? MSDN库在这个问题上很不清楚。

回答

13

您无法将单个套接字绑定到多个端点。 A SocketException(无效的参数错误)在第二次给定的套接字调用Bind()时发生。

正如其他人所说的那样,您可以使用IPAddress.Any来侦听本地计算机上的IPv4地址。但是,如果您只想监听可用IP地址的子集,则必须创建单独的套接字。

+0

好的,谢谢你的明确答案。 – 2009-11-22 04:04:45

+5

不,IPAddress.Any不会将Socket对象绑定到所有IP地址,如果您只是统计IP v6地址。 正确的方法是创建两个Socket对象。然后一个绑定到IPAddress.Any,另一个绑定到IPAddress.IPv6Any。 – 2009-11-22 09:23:21

+0

好点。我的项目仍然只是IPv4,所以当我写回答时,IPv6甚至不是一个考虑因素。 – 2009-11-22 18:50:44

2

是的,IPAddress.Any将侦听所有接口。

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

+0

好吧,这有助于(Bind方法只是说,框架会在监听的地址,这是相当模糊的)。但是如果我只想听取分配给计算机的10个IP地址中的5个,怎么样?我需要5个插座吗?或者我可以用不同的端点多次调用绑定()? – 2009-11-22 02:49:54

+0

是的,你每个地址一个,除非你绑定到Any或IPv6Any。 – 2009-11-22 09:24:29

4

从技术上讲,你的服务器从来没有分配给它的任何IP地址。

相反,可以为各个网络接口分配IP地址。通常,每个NIC都有一个IP地址,但这只是最常见的情况。

如果您想要控制哪些接口正在侦听所选端口上的传入连接,则需要为每个端口创建一个单独的套接字。

+1

是的,我知道你给接口分配了IP地址,但是.NET隐藏了你的接口,并且你只需绑定到端点。我有点困惑,为什么你可以使用IPAddress.Any监听多个接口,但需要多个套接字来监听特定的接口。 – 2009-11-22 03:52:09

+1

我怀疑这是框架设计者的“让常见案例容易实现”的例子,它提供了一个有用的捷径。 – Bevan 2009-11-22 04:13:27

+0

任何和IPv6Any都可以被视为快捷方式。但是你不能要求一个框架为你提供你想要的所有捷径。我完全同意Bevan。 当你玩更多的框架,并开始设计自己的,你会看到它总是很难做出选择。 – 2009-11-22 09:27:03

2

关于IPAddress.Any,MSDN库似乎并不矛盾。绑定DOC

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

说,“最合适”的地址选择,但IPAddress.Any DOC

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

说,这个不变的插座必须侦听活动所有接口。

但是,我被告知这是IPAddress.Any文档是正确的。

(因为我没有足够的代表发表评论,所以增加了这个答案)。

3

我已经对它进行了处理,IPAddress.Any不是正确的方式,它会绑定任何合适的IP地址。在我的情况下,我有2个网卡,我无法解决问题。当我加入

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告诉Windows要侦听的IPv6堆栈。将套接字选项设置为false可以让Windows不将自身限制在IPv6堆栈中,而是监听IPv4堆栈。默认情况下只侦听显式指定的堆栈。

+0

哇,这很漂亮......嗯......非显而易见的;)我认为这并不能证明有选择地聆听多个IP的方法。 – 2015-02-02 16:02:47

+0

对大多数人来说,这可能并不重要,但只有.NET 4或更新版本才支持。 – eAi 2016-04-07 09:42:50