En C #, para usar un TcpClient o, en general, para conectarme a un socket, ¿cómo puedo verificar primero si un determinado puerto está libre en mi máquina?
más información: Este es el código que uso:
TcpClient c;
//I want to check here if port is free.
c = new TcpClient(ip, port);
Respuestas:
Dado que está utilizando un
TcpClient
, eso significa que está comprobando los puertos TCP abiertos. Hay muchos buenos objetos disponibles en el espacio de nombres System.Net.NetworkInformation .Utilice el
IPGlobalProperties
objeto para llegar a una matriz deTcpConnectionInformation
objetos, que luego puede interrogar sobre la IP y el puerto del punto final.fuente
netstat -a -b
. Observe que lasLISTENING
conexiones no están presentes enGetActiveTcpConnections()
. También debe registrarseSystem.Net.IPEndPoints[]
devuelto poripGlobalProperties.GetActiveTcpListeners();
Estás en el extremo equivocado del intertubo. Es el servidor que solo puede tener abierto un puerto en particular. Algún código:
Falla con:
fuente
Cuando configura una conexión TCP, la 4-tupla (source-ip, source-port, dest-ip, dest-port) tiene que ser única; esto es para garantizar que los paquetes se entreguen en el lugar correcto.
Existe una restricción adicional en el lado del servidor de que solo un programa de servidor puede vincularse a un número de puerto entrante (asumiendo una dirección IP; los servidores de múltiples NIC tienen otros poderes, pero no es necesario que los analicemos aquí).
Entonces, en el extremo del servidor, usted:
En el lado del cliente, generalmente es un poco más simple:
No existe ningún requisito de que la IP / puerto de destino sea único, ya que eso daría como resultado que solo una persona a la vez pudiera usar Google, y eso destruiría bastante bien su modelo de negocio.
Esto significa que incluso puede hacer cosas tan maravillosas como FTP de múltiples sesiones, ya que configura varias sesiones donde la única diferencia es su puerto de origen, lo que le permite descargar fragmentos en paralelo. Los torrents son un poco diferentes porque el destino de cada sesión suele ser diferente.
Y, después de todo ese parloteo (lo siento), la respuesta a su pregunta específica es que no necesita especificar un puerto libre. Si se está conectando a un servidor con una llamada que no especifica su puerto de origen, es casi seguro que usará cero debajo de las cubiertas y el sistema le dará uno sin usar.
fuente
Has entendido mal lo que está pasando aquí.
Los parámetros de TcpClient (...) son la IP del servidor y el puerto del servidor al que desea conectarse.
TcpClient selecciona un puerto local transitorio del grupo disponible para comunicarse con el servidor. No es necesario verificar la disponibilidad del puerto local, ya que la capa winsock lo maneja automáticamente.
En caso de que no pueda conectarse al servidor utilizando el fragmento de código anterior, el problema podría ser uno o más de varios. (es decir, la IP y / o el puerto del servidor son incorrectos, el servidor remoto no está disponible, etc.)
fuente
Gracias por este consejo. Necesitaba la misma funcionalidad pero en el lado del servidor para verificar si un puerto estaba en uso, así que lo modifiqué a este código.
fuente
-anb
) y, sin ningún parámetro, muestra la conexión externa y el estado.gracias por la respuesta jro. Tuve que modificarlo para mi uso. Necesitaba comprobar si se estaba escuchando un puerto y si no estaba necesariamente activo. Por esto reemplacé
con
Repetí la matriz de puntos finales comprobando que no se encontró el valor de mi puerto.
fuente
fuente
netstat! Esa es una utilidad de línea de comandos de red que se envía con Windows. Muestra todas las conexiones establecidas actualmente y todos los puertos que se están escuchando. Puede usar este programa para verificar, pero si desea hacer esto desde el código, busque en el espacio de nombres System.Net.NetworkInformation. Es un nuevo espacio de nombres a partir de 2.0. Hay algunas golosinas ahí. Pero eventualmente, si desea obtener el mismo tipo de información que está disponible a través del comando netstat, deberá obtener el resultado P / Invoke ...
Actualización: System.Net.NetworkInformation
Ese espacio de nombres contiene un montón de clases que puede usar para averiguar cosas sobre la red.
No pude encontrar ese viejo fragmento de código, pero creo que puedes escribir algo similar tú mismo. Un buen comienzo es comprobar la API IP Helper . Google MSDN para la función GetTcpTable WINAPI y use P / Invoke para enumerar hasta que tenga la información que necesita.
fuente
Si no me equivoco mucho, puede usar System.Network.whatever para verificar.
Sin embargo, esto siempre implicará una condición de carrera.
La forma canónica de verificar es intentar escuchar en ese puerto. Si recibe un error, ese puerto no estaba abierto.
Creo que esto es parte de por qué bind () y listen () son dos llamadas al sistema separadas.
fuente
Tu dices
Pero siempre puede conectarse a un puerto mientras otros lo están usando si algo está escuchando allí. De lo contrario, el puerto http 80 sería un desastre.
Si tu
falla, entonces no hay nada escuchando allí. De lo contrario, se conectará, incluso si alguna otra máquina / aplicación tiene un enchufe abierto a esa ip y puerto.
fuente
ipGlobalProperties.GetActiveTcpConnections()
no devuelve conexiones en estado de escucha.El puerto se puede utilizar para escuchar, pero sin nadie conectado a él, el método descrito anteriormente no funcionará.
fuente
De los puertos disponibles, excluiría:
Con la siguiente importación:
Puede utilizar la siguiente función para comprobar si un puerto está disponible o no:
Te doy una función similar para aquellos que usan VB.NET :
fuente
Para responder a la pregunta exacta de encontrar un puerto libre (que es lo que necesitaba en mis pruebas unitarias) en dotnet core 3.1, se me ocurrió esto
nota: basé el comentario de @ user207421 sobre el puerto cero, busqué y encontré esto y lo modifiqué ligeramente.
fuente
Tenga en cuenta la ventana de tiempo entre que realiza la verificación y el momento en que intenta realizar la conexión, es posible que algún proceso tome el puerto: TOCTOU clásico . ¿Por qué no intentas conectarte? Si falla, entonces sabrá que el puerto no está disponible.
fuente
No tiene que saber qué puertos están abiertos en su máquina local para conectarse a algún servicio TCP remoto (a menos que desee usar un puerto local específico, pero generalmente ese no es el caso).
Cada conexión TCP / IP se identifica mediante 4 valores: IP remota, número de puerto remoto, IP local, número de puerto local, pero solo necesita conocer la IP remota y el número de puerto remoto para establecer una conexión.
Cuando crea una conexión tcp usando
Su sistema asignará automáticamente uno de los muchos números de puerto locales libres a su conexión. No necesitas hacer nada. También es posible que desee comprobar si hay un puerto remoto abierto. pero no hay mejor manera de hacerlo que simplemente intentando conectarse a él.
fuente
fuente
fuente
Verifique el código de error 10048
fuente
intente esto, en mi caso, el número de puerto para el objeto creado no estaba disponible, así que se me ocurrió esto
fuente