Quiero obtener cualquier puerto TCP abierto aleatorio en localhost en Python. ¿Cuál es la manera más sencilla?obtener puerto TCP abierto en Python
Respuesta
Mi solución actual:
def get_open_port():
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("",0))
s.listen(1)
port = s.getsockname()[1]
s.close()
return port
No es muy agradable y no es 100% correcto, pero funciona por ahora.
¿Por qué la llamada listen()? Para mí, s.getsockname() [1] se completa tan pronto como llamo bind() – ncoghlan
¿Es necesario llamar a 's.shutdown()' antes de 's.close()' en este caso? –
De hecho, me haga lo siguiente en uno de mis programas:
port = random.randint(10000,60000)
Por supuesto, esto es aún más propenso a las colisiones que el código que tiene. Pero nunca tuve un problema con eso. El punto es que, en un momento dado, la mayoría de los puertos con numeración alta no están en uso y si solo elige uno al azar, es poco probable tener un conflicto con otro proceso. Si hace algo así como la solución que publicó en su respuesta (abrir un socket y tomar su número de puerto), es casi seguro que el puerto no va a entrar en conflicto. Entonces, si esto es algo que solo usará usted (en lugar de algo que va a lanzar al público), piense si vale la pena encontrar una solución verdaderamente a prueba de balas. Las probabilidades son que nunca harán la diferencia.
Motivado por el comentario de Marcelo Cantos sobre su pregunta, añadiré que la solución estándar en casos como este es hacer que el proceso que utilizará el puerto se vincule y luego compartir esa información con cualquier otro programa que necesite eso. Por lo general, hará algo así como escribir un archivo temporal que contenga el número de puerto en alguna ubicación estándar en el sistema de archivos. Dado que el proceso con el que estás trabajando no hace eso, en cierto sentido cualquier solución que se te ocurra será un truco. Pero, de nuevo, si es solo para tu propio uso, probablemente esté bien.
Esta es mi versión, sin embargo, no es realmente aleatoria si especifica un rango de puertos. Esto también sufrirá por las condiciones de carrera, pero esta es la mejor forma que conozco si necesita conocer el puerto con anticipación.
import socket
import errno
import contextlib
reserved_ports = set()
def get_open_port(lowest_port = 0, highest_port = None, bind_address = '', *socket_args, **socket_kwargs):
if highest_port is None:
highest_port = lowest_port + 100
while lowest_port < highest_port:
if lowest_port not in reserved_ports:
try:
with contextlib.closing(socket.socket(*socket_args, **socket_kwargs)) as my_socket:
my_socket.bind((bind_address, lowest_port))
this_port = my_socket.getsockname()[1]
reserved_ports.add(this_port)
return this_port
except socket.error as error:
if not error.errno == errno.EADDRINUSE:
raise
assert not lowest_port == 0
reserved_ports.add(lowest_port)
lowest_port += 1
raise Exception('Could not find open port')
Desafortunadamente, esto no es 100% a prueba de fallas y puede devolver True cuando el puerto está realmente en uso por otra aplicación. No he descifrado por qué, pero.bind() no siempre fallará cuando otro proceso ya esté escuchando en el puerto. – Joe
@Joe ¿es posible que la otra aplicación esté vinculada a una dirección diferente pero con el mismo puerto? o familia de dirección diferente? –
Es posible. Todo lo que sé es que, en mi caso, la aplicación de servidor que estaba tratando de iniciar no pudo abrir el puerto aunque el código anterior decía que el puerto era libre. La otra aplicación era erl.exe (erlang), que obtuve a través de la configuración de RabbitMQ si quieres probarlo por ti mismo. – Joe
Los puertos efímeros básicamente se encuentran en el rango de 49152 - 65535. si desea comprobar los puertos en serie más grande, entonces simplemente cambiar los valores en randint.
import pustil
from random import randint
def getfreeport():
port = randint(49152,65535)
portsinuse=[]
while True:
conns = pstuil.net_connections()
for conn in conns:
portsinuse.append(con.laddr[1])
if port in portsinuse:
port = randint(49152,65535)
else:
break
return port
El puerto libre se puede encontrar al vincular un socket a un puerto seleccionado por el sistema operativo. Después de que el sistema operativo selecciona un puerto, se puede eliminar el zócalo. Sin embargo, esta solución no es resistente a las condiciones de carrera: en el corto tiempo entre obtener el número de puerto libre y usar este puerto, otro proceso puede usar este puerto.
def find_free_port():
s = socket.socket()
s.bind(('', 0)) # Bind to a free port provided by the host.
return s.getsockname()[1] # Return the port number assigned.
- 1. ¿Liberar un puerto TCP/IP?
- 2. que usa un puerto TCP?
- 3. Python TCP aplicación pila
- 4. Python PySerial.¿Cómo saber si un puerto ya está abierto?
- 5. ¿Cómo cerrar una conexión TCP por puerto?
- 6. Compruebe si un puerto está abierto
- 7. Necesito ayuda para obtener el número de puerto TCP y la dirección IP en C
- 8. Ruby: compruebe si hay un puerto abierto
- 9. para TCP y UDP solicitudes en el mismo puerto
- 10. iPhone TCP Communication
- 11. Obtener ruta desde el archivo abierto en Python
- 12. ¿El puerto cambia cuando el servidor acepta una conexión TCP?
- 13. comprobar si el puerto está abierto en ANT
- 14. Python diccionario enviar throught TCP
- 15. Enlace de puerto de Python
- 16. Puerto OAuth para Python 3
- 17. ¿Cómo me conecto a un puerto UDP en Python?
- 18. Pruebe si el puerto está abierto y reenviado usando PHP
- 19. Python: urllib.urlopen puerto no numérico
- 20. Detectar el puerto Arduino en Python
- 21. FastCGI en el puerto
- 22. Java TCP Socket Sniffing
- 23. Es el puerto utilizado por un cliente TCP para conectarse a un servidor no disponible para otros servidores TCP
- 24. REDIRECCIONE un puerto en ip6tables
- 25. Nombre de puerto a servicio en Java?
- 26. Obtener puerto aleatorio para socket UDP
- 27. Cómo determinar el puerto tcp utilizado por el proceso de Windows en C#
- 28. Determinación de la dirección IP y el puerto de una conexión TCP/IP entrante en Erlang
- 29. ¿Cómo elegir un número de puerto gratis en python?
- 30. ¿Cómo se puede encontrar un puerto de servidor TCP gratuito usando Ruby?
Esto es como perros persiguiendo coches: ¿qué vas a hacer cuando lo consigas? –
Necesito un número de puerto TCP para otra aplicación de consola que necesita un puerto como parámetro donde se escuchará. – Albert
Hay una condición de carrera obvia (aunque menor) con el enfoque que está contemplando. El puerto puede tomarse para cuando lo pase por el otro proceso. ¿Eres dueño del código del otro proceso? Si es así, podría ser mejor obtener un puerto aleatorio e informarlo al primer proceso. –