Saltar al contenido

TCP: ¿pueden dos sockets diferentes compartir un puerto?

Este team de trabajo ha pasado mucho tiempo buscando la solución a tu duda, te dejamos la resolución por eso esperamos resultarte de mucha apoyo.

Solución:

Escucha TCP/HTTP en puertos: ¿Cuántos usuarios pueden compartir el mismo puerto?

Entonces, ¿qué sucede cuando un servidor escucha las conexiones entrantes en un puerto TCP? Por ejemplo, supongamos que tiene un servidor web en el puerto 80. Supongamos que su computadora tiene la dirección IP pública 24.14.181.229 y la persona que intenta conectarse tiene la dirección IP 10.1.2.3. Esta persona puede conectarse contigo abriendo un socket TCP a 24.14.181.229:80. Suficientemente simple.

Intuitivamente (y erróneamente), la mayoría de la gente asume que se parece a esto:

    Local Computer    | Remote Computer
    --------------------------------
    :80     | :80

    ^^ not actually what happens, but this is the conceptual model a lot of people have in mind.

Esto es intuitivo, porque desde el punto de vista del cliente, tiene una dirección IP y se conecta a un servidor en IP:PORT. Dado que el cliente se conecta al puerto 80, ¿su puerto también debe ser 80? Esto es algo sensato de pensar, pero en realidad no es lo que sucede. Si eso fuera correcto, solo podríamos atender a un usuario por dirección IP extranjera. Una vez que una computadora remota se conecta, acapararía la conexión del puerto 80 al puerto 80, y nadie más podría conectarse.

Hay que entender tres cosas:

1.) En un servidor, un proceso es escuchando en un puerto. Una vez que obtiene una conexión, la pasa a otro hilo. La comunicación nunca acapara el puerto de escucha.

2.) El sistema operativo identifica de forma única las conexiones mediante la siguiente tupla de 5: (IP local, puerto local, IP remota, puerto remoto, protocolo). Si algún elemento en la tupla es diferente, entonces esta es una conexión completamente independiente.

3.) Cuando un cliente se conecta a un servidor, elige un puerto de origen de orden superior aleatorio y no utilizado. De esta forma, un solo cliente puede tener hasta ~64k conexiones al servidor para el mismo puerto de destino.

Entonces, esto es realmente lo que se crea cuando un cliente se conecta a un servidor:

    Local Computer   | Remote Computer           | Role
    -----------------------------------------------------------
    0.0.0.0:80       |                     | LISTENING
    127.0.0.1:80     | 10.1.2.3:    | ESTABLISHED

Mirando lo que realmente sucede

Primero, usemos netstat para ver qué está pasando en esta computadora. Usaremos el puerto 500 en lugar del 80 (porque suceden muchas cosas en el puerto 80, ya que es un puerto común, pero funcionalmente no hace la diferencia).

    netstat -atnp | grep -i ":500 "

Como era de esperar, la salida está en blanco. Ahora vamos a iniciar un servidor web:

    sudo python3 -m http.server 500

Ahora, aquí está el resultado de ejecutar netstat nuevamente:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State  
    tcp        0      0 0.0.0.0:500             0.0.0.0:*               LISTEN      - 

Así que ahora hay un proceso que está escuchando activamente (Estado: LISTEN) en el puerto 500. La dirección local es 0.0.0.0, que es el código para “escuchar todas las direcciones IP”. Un error fácil de cometer es escuchar solo en el puerto 127.0.0.1, que solo aceptará conexiones desde la computadora actual. Entonces, esto no es una conexión, esto solo significa que un proceso solicitó vincular () a la IP del puerto, y ese proceso es responsable de manejar todas las conexiones a ese puerto. Esto sugiere la limitación de que solo puede haber un proceso por computadora escuchando en un puerto (hay formas de evitarlo usando multiplexación, pero este es un tema mucho más complicado). Si un servidor web está escuchando en el puerto 80, no puede compartir ese puerto con otros servidores web.

Así que ahora, conectemos un usuario a nuestra máquina:

    quicknet -m tcp -t localhost:500 -p Test payload.

Este es un script simple (https://github.com/grokit/quickweb) que abre un socket TCP, envía la carga (“Test payload” en este caso), espera unos segundos y se desconecta. Hacer netstat nuevamente mientras esto sucede muestra lo siguiente:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State  
    tcp        0      0 0.0.0.0:500             0.0.0.0:*               LISTEN      -
    tcp        0      0 192.168.1.10:500        192.168.1.13:54240      ESTABLISHED -

Si se conecta con otro cliente y vuelve a hacer netstat, verá lo siguiente:

    Proto Recv-Q Send-Q Local Address           Foreign Address         State  
    tcp        0      0 0.0.0.0:500             0.0.0.0:*               LISTEN      -
    tcp        0      0 192.168.1.10:500        192.168.1.13:26813      ESTABLISHED -

… es decir, el cliente usó otro puerto aleatorio para la conexión. Así que nunca hay confusión entre las direcciones IP.

A servidor socket escucha en un solo puerto. Todas las conexiones de clientes establecidas en ese servidor están asociadas con ese mismo puerto de escucha en el lado del servidor de la conexión Una conexión establecida se identifica de forma única mediante la combinación de pares de IP/puerto del lado del cliente y del lado del servidor. Múltiples conexiones en el mismo servidor pueden compartir el mismo lado del servidor Par IP/Puerto siempre que estén asociados a diferentes lado del cliente Pares IP/Puerto, y el servidor podría manejar tantos clientes como lo permitan los recursos disponibles del sistema.

Sobre el lado del clientees una práctica común que las nuevas conexiones salientes utilicen un lado del cliente port, en cuyo caso es posible que se quede sin puertos disponibles si realiza muchas conexiones en poco tiempo.

Un enchufe conectado se asigna a un nuevo puerto (dedicado)

Esa es una intuición común, pero es incorrecta. Un enchufe conectado no está asignado a un puerto nuevo/dedicado. La única restricción real que debe satisfacer la pila TCP es que la tupla de (dirección_local, puerto_local, dirección_remota, puerto_remoto) debe ser única para cada conexión de socket. Por lo tanto, el servidor puede tener muchos sockets TCP utilizando el mismo puerto local, siempre que cada uno de los sockets del puerto esté conectado a una ubicación remota diferente.

Consulte el párrafo “Par de sockets” en: http://books.google.com/books?id=ptSC4LpwGA0C&lpg=PA52&dq=socket%20pair%20tuple&pg=PA52#v=onepage&q=socket%20pair%20tuple&f=false

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *