2009-11-22 19 views
6

Si mi servidor tiene varias direcciones IP asignadas, y me gustaría escuchar algunas (o todas), ¿cómo hago para hacerlo?¿Cómo se escucha en múltiples direcciones IP?

¿Necesito crear un nuevo socket para cada dirección IP y vincularlo? ¿Puedo vincular múltiples direcciones IP a un solo socket? ¿IPAddress.Any escucha en todas las direcciones IP? La biblioteca de MSDN no está muy clara al respecto.

Respuesta

13

No se puede vincular un solo socket a múltiples puntos finales. Se produce un SocketException (error de argumento no válido) la segunda vez que llama al Bind() para un socket dado.

Como han dicho otros, puede usar IPAddress.Any para escuchar las direcciones IPv4 en la máquina local. Sin embargo, si solo desea escuchar en un subconjunto de las direcciones IP disponibles, tendrá que crear sockets separados.

+0

Ok, gracias por la respuesta definitiva. –

+5

No, IPAddress.Any no vincula los objetos Socket a todas las direcciones IP si solo cuenta las direcciones IP v6. La forma correcta es crear dos objetos Socket. Luego se une a IPAddress.Any, y el otro se une a IPAddress.IPv6Any. –

+0

Buen punto. Mi proyecto sigue siendo únicamente IPv4, por lo que IPv6 ni siquiera fue una consideración cuando escribí mi respuesta. –

2

Sí, dirección IP.Todo escuchará en todas las interfaces.

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

+0

Ok, que ayuda (el método del lazo se limita a decir que el marco recoge la dirección para escuchar en, que es bastante vaga). Pero, ¿qué pasa si solo quiero escuchar en 5 de las 10 direcciones IP asignadas a la computadora? ¿Necesito 5 enchufes para eso? o ¿puedo llamar a Bind() varias veces con diferentes puntos finales? –

+0

Sí, uno por dirección, a menos que se una a Any o IPv6Any. –

4

Técnicamente, el servidor no tiene ninguna de las direcciones IP asignadas a la misma.

En su lugar, se pueden asignar direcciones IP a las interfaces de red individuales. Por lo general, cada NIC recibe una dirección IP, pero ese es solo el caso más común.

Si desea controlar qué interfaces están escuchando las conexiones entrantes en su puerto elegido, necesitará crear un socket separado para cada una.

+1

Sí, soy consciente de que asigna direcciones IP a las interfaces, pero .NET lo oculta y simplemente se vincula a los puntos finales. Estoy un poco confundido acerca de por qué puedes escuchar en varias interfaces con IPAddress. Cualquiera, pero necesitas múltiples tomas para escuchar las específicas. –

+1

Sospecho que es un caso de "vamos a hacer el caso común facilidad de hacer" por los diseñadores del marco, proporcionando un acceso directo útil. – Bevan

+0

Any e IPv6Any se pueden considerar como accesos directos. Pero no podría pedirle a un marco que le proporcione todos los accesos directos que desee. Estoy totalmente de acuerdo con Bevan. Cuando juegas más con los marcos y de empezar a diseñar su propia, verá que siempre es difícil tomar decisiones. –

2

La biblioteca de MSDN parece contradictoria con respecto a IPAddress.Any. El documento Enlazar

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

dice que se elige la dirección de 'más adecuado', pero el doc IPAddress.Any

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

dice que con esta constante la toma deberá detectar la actividad en todas las interfaces

Sin embargo, me dijeron que es la dirección IP. Cualquier documento que sea correcto.

(agregando esto como una respuesta ya que no tengo suficientes representantes para dejar comentarios).

3

He trabajado en ello, IPAddress.Cualquier no es el camino correcto, se unirá a cualquier dirección IP adecuada. En mi caso tengo 2 NIC y no pude solucionar el problema. Cuando agregué

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

Funcionó bien.

3

Si desea escuchar en todas las direcciones IPv4 e IPv6, utilice este código:

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

IPv6Any indica a Windows para escuchar en la pila IPv6. Establecer la opción de socket en false le dice a Windows que no se limite solo a la pila de IPv6, sino que también escuche en la pila de IPv4. El valor predeterminado es escuchar solo en la pila explícitamente especificada.

+0

Wow, eso es bastante ... ummm .. no evidente;) Supongo que esto no prueba una forma de escuchar múltiples IP de forma selectiva. –

+0

Esto puede no importarle a la mayoría de las personas, pero esto solo es compatible con .NET 4 o posterior. – eAi

Cuestiones relacionadas