¿Cómo puedo encontrar un puerto TCP libre con NetTcpBinding (WCF) (para que un servidor pueda enlazarlo)?

StackOverflow https://stackoverflow.com/questions/1803065

Pregunta

Buscar el siguiente puerto TCP en .Net dice cómo haga esto en .net sin procesar, pero no cómo hacerlo de manera segura con WCF.

En mis pruebas de unidad, necesito usar NetTcpBinding, No deseo codificar el puerto que está utilizando .

Por lo tanto, ¿cómo puedo hacer que NetTcpBinding elija automáticamente un puerto libre cuando se utiliza en mi ServiceHost?

¿Cómo puedo hacer que me diga el puerto (o la dirección de punto final completa) que ha elegido?

¿O cómo puedo usar .NET para encontrar un puerto que sea válido para que un servidor se enlace?


Dado que mi recompensa no dio lugar a nuevas respuestas, creo que podemos asumir que no hay una buena respuesta.

¿Fue útil?

Solución 6

Actualmente, creo que esto no es posible, gracias a todos los que proporcionaron trabajo a rondas.

Otros consejos

No es necesario que ruede su propia lógica de búsqueda de puertos: Windows seleccionará un puerto libre si lo especifica como 0. Luego, puede averiguar qué puerto se asignó interrogando a los despachadores, de este modo:

// Specify port 0, this will cause Windows to choose a free port
var baseUri = new Uri("net.tcp://" + Dns.GetHostEntry("").HostName + ":0");
host = new WebServiceHost(typeof(MyService));
var endPoint = host.AddServiceEndpoint(typeof(IMyService), new NetTcpBinding(), baseUri);

 // Tell WCF to actually bind to a free port instead of 0
 endPoint.ListenUriMode = ListenUriMode.Unique;

 host.Open();

 // Now that the host has bound to a specific port, we can find out which one it chose
 return host.ChannelDispatchers.First().Listener.Uri;

Establece el puerto a cero. Eso le permite al sistema operativo elegir un puerto disponible para usted. Si necesita determinar qué puerto se usó, puede consultarlo desde el socket después de que se haya enlazado localmente.

Esto es lo que hago: comenzar con un puerto aleatorio en el rango 1025-2000 (rango elegido arbitrariamente). Intento enlazarlo y si falla, detecto la excepción. Luego subo un puerto ( puerto = puerto% 2000 + 1025 ) hasta que termine. Si ningún puerto está vinculado, renuncio a fallar la prueba.

4 años después .. Actualmente tenemos una solución, configurando ListenUriMode en Unique , como se indica en MSDN

Aquí hay un pequeño ejemplo de una configuración de punto final

<endpoint address="service"
          binding="netTcpBinding"
          contract="Iservice"
          name="TcpBinding"
          bindingConfiguration="netTcpBindingNoSec"
          listenUriMode="Unique"
          />

Y ahora el siguiente problema: si el puerto es dinámico, ¿cómo pueden saberlo los clientes? Como se indica en ESTA RESPUESTA puede usar WCF DISCOVERY : requiere una pequeña configuración en el servidor y del lado del cliente, pero funciona bien (con el único problema que tarda unos segundos en obtenerlo, por defecto, 20 segundos, pero no tengo problemas para forzarlo a 5)

al usar un puerto alto aleatorio, puede generar colisiones con otros procesos del servidor que deseen iniciar después de su programa. simplemente use cero como número de puerto y deje que el sistema operativo se preocupe por las reservas (/ etc / services en unix, no sé cómo lo maneja Windows).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top