2010-11-29 13 views
10

¿Quién sabe cómo se elige el puerto cuando estoy usando el método accept de la clase ServerSocket? ¿Es posible definir un rango para los puertos de los que puede elegir el método? ¿Puedo 'tomar' puertos uno por uno solo en orden?Método ServerSocket accept()

ServerSocket sSocket = new ServerSocket(5050); 
Socket socket = sSocket.accept(); 

From the book

+0

prueba getLocalPort y verifica si eso es cierto. – Codemwnci

+4

¿Es un buen libro lo que estás leyendo? "simple socket viejo" me suena extraño. –

+0

Sí, es Head First Java, un libro para principiantes. – Eugene

Respuesta

20

El diagrama es incorrecto (y se enumera en el unconfirmed errata en el sitio de O'Reilly).

El cliente eligesu puerto al azar (que no es necesario hacer nada especial en Java) y se conecta con el servidor en el que sea el puerto especificados. Usando la herramienta de línea de comandos netstat se puede ver esto - en primer lugar, sólo el servidor socket de escucha con ningún cliente:

 
[email protected]:~$ netstat -n -a 
Active Internet connections (including servers) 
Proto Recv-Q Send-Q Local Address   Foreign Address  (state) 
... 
tcp46  0  0 *.5050     *.*     LISTEN 
... 

(hay un montón de otras entradas, que acabo de extraer las no relacionadas)

Ahora con 1 cliente que se conecta desde el host local (127.0.0.1):

 
[email protected]:~$ netstat -n -a 
Active Internet connections (including servers) 
Proto Recv-Q Send-Q Local Address   Foreign Address  (state) 
... 
tcp4  0  0 127.0.0.1.64895  127.0.0.1.5050  ESTABLISHED <- 1 
tcp4  0  0 127.0.0.1.5050   127.0.0.1.64895  ESTABLISHED <- 2 
tcp46  0  0 *.5050     *.*     LISTEN  <- 3 
... 

Puesto que el cliente se conecta desde la misma máquina, vemos dos conexiones establecidas - uno del cliente al servidor (1), y el otro de servidor a cliente (2). Tienen direcciones locales y extranjeras opuestas (ya que están hablando entre sí) y se puede ver que el extremo del servidor sigue utilizando el puerto 5050 mientras que el socket del servidor original (3) continúa escuchando en el mismo puerto.

(estos son de la Mac, pero Windows/Linux también tienen netstat dar una salida similar)

+0

Muchas gracias. – Eugene

+0

Hola SimonJ, ¿podrías explicar por qué el lado del servidor podría usar el mismo puerto de socket? Gracias ! – MrROY

+0

@MrROY Porque el cliente elige su puerto local al azar, como dice en la respuesta. – EJP

0

El ServerSocket define el puerto como parte del constructor. Si no especifica un puerto, el socket no está vinculado (es decir, no se puede acceder).

Para obtener el puerto del zócalo de conexión, use getPort() y no getLocalPort(). El segundo te dará el puerto en tu servidor.

+0

He agregado una nota a mi pregunta. Por favor, eche un vistazo en la segunda línea. Gracias – Eugene

+1

No estoy muy seguro de lo que quieres decir. 100 tomas conectadas a su servidor se conectarán a través del puerto 5050. Si se refiere al puerto de la máquina que se conecta a usted, entonces use getPort(). – Codemwnci

0

Puede pasar 0 como un número de puerto para crear un socket de servidor en cualquier puerto libre, o hacer un método como este para crear un socket de servidor para cualquier puerto libre en el rango dado:

public java.net.ServerSocket createServerSocket(int rangeStart, int rangeEnd) 
          throws java.io.IOException { 
    for(int port=rangeStart; port<=randeEnd; port++) { 
    try { 
     return new ServerSocket(port); 
    } catch(java.net.BindException be) { 
     // debug/warning here 
     continue; 
    } 
    } 
    throw new java.io.IOException("Failed to create a server socket, all ports between " + 
           rangeStart + " - " + rangeEnd + " are already in use."); 
} 

El loop no se ocupa de otra excepción (SecurityException por ejemplo), pero puede agregarla.

+0

ServerSocket (i)? ¿Querías decir ServerSocket (puerto)? – Eugene

+0

@AndriodNood seguro, gracias, corregido. – khachik

+0

¿No funcionará esto, porque cuando devuelve ServerSocket por primera vez, detiene la función? – Arin

2

Una conexión TCP se compone de cuatro partes:

  • IP del cliente
  • Puerto de cliente
  • Servidor IP
  • Puerto del servidor

No puede ser, por ejemplo, varios clientes conectado al mismo puerto de servidor, siempre que los clientes no tengan la misma IP y el mismo prt, está bien. Y para esa parte, el sistema operativo se ocupa.

Así que está bien escuchar solo en un puerto.

+0

Gracias por su aclaración. Acabo de subir una imagen del libro, ¿puedes echar un vistazo, por favor? – Eugene

+0

@Eugene Olvida el libro. Está incorrecto. – EJP

5

Se eligió el puerto, cuando dijiste nueva ServerSocket (5050). Todo lo relacionado con el uso de un puerto diferente para el socket aceptado es 100% BS.

Cuestiones relacionadas