2011-10-09 6 views
7

Soy el responsable del mantenimiento del módulo XML-LibXSLT y una de las pruebas necesita acceder a una URL no existente. El problema fue que alguien informó que en su sistema existía la URL, así que decidí asignar un puerto aleatorio en localhost donde estoy seguro de que no habrá servicio web. Se hizo así:Perl: cómo reservar de manera portátil un puerto TCP (por lo que habrá una URL no disponible)

# We reserve a random port to make sure the localhost address is not 
# valid. See: 
# 
# https://rt.cpan.org/Ticket/Display.html?id=52422 

my $sock = IO::Socket::INET->new(
    Proto => 'tcp', 
); 

my $port = $sock->sockport(); 

$file = "http://localhost:${port}/allow.xml"; 

Ahora, el problema es que el puerto $ se define y válido (con el valor de un puerto reservado) en Linux, pero no parece funcionar en Windows - ver este error informe - https://rt.cpan.org/Ticket/Display.html?id=71456. Mi pregunta es: ¿cómo puedo reservar un puerto nuevo, aleatorio, aún no ocupado de forma portátil en UNIXes, Mac OS X y Windows en Perl 5?

Saludos,

Shlomi pescado

Respuesta

5

Debe poder bind a la dirección de bucle invertido utilizando el puerto 0 (para que se le asigne un puerto). Para obtener puntos de bonificación, puede intentar connect el conector en sí mismo (probablemente no sea necesario en ninguna parte, pero debe garantizar que tiene una dirección)

+0

+1. El connect() es innecesario. – EJP

+0

@EJP: Es cierto, apenas recuerdo que Windows adoptó un enfoque un tanto perezoso para la asignación de puertos, al menos para los zócalos enlazados 'INADDR_ANY'. – Hasturkun

+0

El puerto se asigna en la hora de enlace(). – EJP

0

Sospecho (pero no puedo demostrar de aquí) que en Windows el número de puerto en realidad no esté previsto hasta el momento en el zócalo de hecho comienza a escuchar.

Sin embargo, tener ese socket realmente escuchando evitará que la prueba falle tan rápido como podría hacerlo ya que la conexión TCP inicial tendría éxito.

¿Ha considerado simplemente indicar la URL en test.example.com, lo que está garantizado que no existe?

+0

[http://example.com] (http://example.com) - no se puede registrar, pero sí existe. –

+0

Preferiría no tener acceso a un recurso interconectado aquí porque la red externa puede no estar disponible y porque no quiero que las pruebas "telefoneen" en algún lugar sin el consentimiento del usuario. –

+0

@ e.dan es por eso que sugerí un subdominio – Alnitak

4

Quiere bind el conector a una dirección + puerto. Esto sucederá si especifica un LocalAddr (o LocalHost). Si no especifica un puerto (o especifica el puerto cero), se seleccionará un puerto libre para usted.

use strict; 
use warnings; 
use 5.010; 

use IO::Socket::INET qw(INADDR_ANY); 

my $sock = IO::Socket::INET->new(
    Proto  => 'tcp', 
    LocalAddr => INADDR_ANY, 
); 

my $port = $sock->sockport(); 

say $port; # 60110 

Creo que solo quiere aceptar conexiones del adaptador de bucle invertido. Si es así, use INADDR_LOOPBACK en lugar de INADDR_ANY.

Cuestiones relacionadas