2008-09-22 12 views
10

En Java puede dar el número cero como un parámetro único para el constructor Socket o DatagramSocket. Java vincula ese socket a un puerto libre a continuación. ¿Es posible limitar la búsqueda del puerto a un rango específico?¿Cómo se especifica un rango de puertos para sockets Java?

+0

Bueno, para que los usuarios no privilegiados que ya se limita a> 1024 en * nix: P – freespace

+0

Por desgracia, se ejecutan en Windows;) –

Respuesta

7

Hrm, después de leer los documentos, no creo que puedas. Puede enlazar a cualquier puerto, luego volver a enlazar si no es aceptable, o vincularse repetidamente a un puerto en su rango hasta que tenga éxito. El segundo método va a ser más "eficiente".

Estoy inquieto por esta respuesta, porque es ... poco elegante, pero realmente no puedo encontrar nada más, ya sea:/

+2

También debe tener en cuenta que a veces hay implicaciones de seguridad al hacer una búsqueda lineal de un puerto libre. Si usa el puerto A para el cliente 1 y el puerto A + 1 para el siguiente cliente, entonces el cliente 1 puede adivinar el puerto que va a usar para otro cliente. – Darron

2

Encuadernación la toma a cualquier puerto libre es (generalmente) una característica de la soporte de socket del sistema operativo; no es específico de Java. Solaris, por ejemplo, admite el ajuste del rango de puertos efímeros mediante el comando ndd. Pero solo root puede ajustar el rango y afecta a todo el sistema, no solo a tu programa.

Si el comportamiento de encuadernación efímero regular no se ajusta a sus necesidades, probablemente tendrá que escribir el suyo usando Socket.bind().

0

Puede echar un vistazo al código java que implementa la función que está utilizando. La mayoría de las bibliotecas de Java están escritas en Java, por lo que puede ver lo que necesita allí.

Asumiendo que @Kenster tenía razón y es una operación del sistema, puede que tenga que simplemente iterar sobre los puertos intentando unirlos a cada uno o probarlos. Aunque es un poco doloroso, no debería ser más que unas pocas líneas de código.

1

Aquí está el código que necesita:

public static Socket getListeningSocket() { 
    for (int port = MIN_PORT ; port <= MAX_PORT ; port++) 
    { 
     try { 
      ServerSocket s = new ServerSocket(port); 
      return s;  // no exception means port was available 
     } catch (IOException e) { 
      // try the next port 
     } 
    } 
    return null; // port not found, perhaps throw exception? 
} 
+3

Debería capturar BindException, que es el que se inició cuando el puerto ya está en uso. – Chochos

Cuestiones relacionadas