¿Pueden dos aplicaciones escuchar el mismo puerto?

¿Pueden dos aplicaciones en la misma máquina vincularse al mismo puerto y dirección IP? Dando un paso más, ¿puede una aplicación escuchar las solicitudes provenientes de una determinada IP y la otra a otra IP remota? Sé que puedo tener una aplicación que comience dos hilos (o tenedores) para tener un comportamiento similar, pero ¿pueden dos aplicaciones que no tienen nada en común hacer lo mismo?

Para TCP, no. Solo puede tener una aplicación escuchando en el mismo puerto a la vez. Ahora bien, si tuviera 2 tarjetas de red, podría hacer que una aplicación escuche en la primera IP y la segunda en la segunda IP usando el mismo número de puerto.

Para UDP (Multicast), múltiples aplicaciones pueden suscribirse al mismo puerto.

Sí (para TCP) puede hacer que dos progtwigs escuchen en el mismo socket, si los progtwigs están diseñados para hacerlo. Cuando el primer progtwig crea el socket, asegúrese de que la opción SO_REUSEADDR esté configurada en el socket antes de bind() . Sin embargo, esto puede no ser lo que quieres. Lo que hace esto es que una conexión TCP entrante se dirigirá a uno de los progtwigs, no a ambos, por lo que no duplica la conexión, solo permite que dos progtwigs realicen el servicio de la solicitud entrante. Por ejemplo, los servidores web tendrán múltiples procesos, todos escuchando en el puerto 80, y el O / S envía una nueva conexión al proceso que está listo para aceptar nuevas conexiones.

 SO_REUSEADDR 

Permite que otros sockets se bind() a este puerto, a menos que haya un socket de escucha activo vinculado al puerto. Esto le permite evitar los mensajes de error “Dirección ya en uso” cuando intenta reiniciar su servidor después de un locking.

En principio, no.

No está escrito en piedra; pero es la forma en que se escriben todas las API: la aplicación abre un puerto, se encarga de él y el sistema operativo lo notifica (mediante ese identificador) cuando llega una conexión de cliente (o un paquete en caso UDP).

Si el SO permitió que dos aplicaciones abrieran el mismo puerto, ¿cómo sabría cuál notificar?

Pero … hay formas de evitarlo

  1. Como señaló Jed, podría escribir un proceso ‘maestro’, que sería el único que realmente escucha en el puerto y notifica a los demás, utilizando cualquier lógica que desee para separar las solicitudes de los clientes.
    • En Linux y BSD (al menos) puede configurar reglas de “reasignación” que redirijan los paquetes del puerto “visible” a diferentes (donde las aplicaciones están escuchando), de acuerdo con cualquier criterio relacionado con la red (tal vez la red de origen, o alguna formas simples de equilibrio de carga).

Sí.

  1. Múltiples sockets TCP de escucha, todos vinculados al mismo puerto, pueden coexistir, siempre que estén vinculados a diferentes direcciones IP locales. Los clientes pueden conectarse a cualquiera que necesiten. Esto excluye 0.0.0.0 ( INADDR_ANY ).

  2. Múltiples receptáculos aceptados pueden coexistir, todos aceptados desde el mismo socket de escucha, todos mostrando el mismo número de puerto local que el socket de escucha.

  3. Múltiples sockets UDP, todos vinculados al mismo puerto, pueden todos coexistir siempre que tengan la misma condición que en (1) o que todos tengan la opción SO_REUSEADDR establecida antes del enlace.

  4. Los puertos TCP y los puertos UDP ocupan diferentes espacios de nombres, por lo que el uso de un puerto para TCP no impide su uso para UDP, y viceversa.

Referencia: Stevens & Wright, TCP / IP Illustrated, Volumen II.

No. Solo una aplicación puede vincularse a un puerto a la vez, y el comportamiento si el enlace es forzado es indeterminado.

Con los zócalos de multidifusión, que suenan como nada cerca de lo que desea, más de una aplicación puede vincularse a un puerto, siempre que SO_REUSEADDR esté configurado en las opciones de cada zócalo.

Puede lograr esto escribiendo un proceso “maestro”, que acepta y procesa todas las conexiones, y luego las entrega a sus dos aplicaciones que necesitan escuchar en el mismo puerto. Este es el enfoque que los servidores web y tal toman, ya que muchos procesos necesitan escuchar 80.

Más allá de esto, estamos entrando en detalles: etiquetó tanto TCP como UDP, ¿cuál es? Además, ¿qué plataforma?

Sí Definitivamente . Por lo que recuerdo Desde la versión 3.9 del kernel (No estoy seguro en la versión) en adelante, se presentó el soporte para el SO_REUSEPORT . SO_RESUEPORT permite vincular exactamente el mismo puerto y dirección, siempre que el primer servidor establezca esta opción antes de enlazar su socket.

Funciona tanto para TCP como para UDP . Consulte el enlace para más detalles: SO_REUSEPORT

Nota : La respuesta aceptada ya no es válida según mi opinión.

Puede tener una aplicación escuchando en un puerto para una interfaz de red. Por lo tanto, podrías tener:

  1. httpd escuchando en una interfaz accesible remotamente, p. ej. 192.168.1.1:80
  2. otro daemon escuchando en 127.0.0.1:80

El caso de uso de muestra podría ser el uso de httpd como un equilibrador de carga o un proxy.

Otra forma es usar un progtwig que escuche en un puerto que analiza el tipo de tráfico (ssh, https, etc.) que redirige internamente a otro puerto en el que está escuchando el servicio “real”.

Por ejemplo, para Linux, sslh: https://github.com/yrutschle/sslh

Si al menos una de las direcciones IP remotas ya es conocida, estática y está dedicada a hablar solo con una de sus aplicaciones, puede usar la regla iptables (tabla nat, cadena PREROUTING) para redirigir el tráfico entrante desde esta dirección a un puerto local “compartido”. cualquier otro puerto donde la aplicación apropiada realmente escuche.

Si y no. Solo una aplicación puede escuchar activamente en un puerto. Pero esa aplicación puede legar su conexión a otro proceso. Entonces, podría tener múltiples procesos trabajando en el mismo puerto.

Sí.

De este artículo:
https://lwn.net/Articles/542629/

La nueva opción de socket permite que varios sockets en el mismo host se unan al mismo puerto

Cuando crea una conexión TCP, solicita conectarse a una dirección TCP específica, que es una combinación de una dirección IP (v4 o v6, según el protocolo que esté utilizando) y un puerto.

Cuando un servidor escucha las conexiones, puede informar al kernel que le gustaría escuchar una dirección IP y un puerto específicos, es decir, una dirección IP, o en todas las direcciones IP de los hosts, cada una en un puerto específico, que es efectivamente escuchando en muchas “direcciones TCP” diferentes (p. ej., 192.168.1.10:8000, 127.0.0.1:8000, etc.)

No, no puede tener dos aplicaciones escuchando en la misma “dirección TCP”, porque cuando llega un mensaje, ¿cómo sabría el núcleo a qué aplicación dar el mensaje?

Sin embargo, en la mayoría de los sistemas operativos puede configurar varias direcciones IP en una única interfaz (por ejemplo, si tiene 192.168.1.10 en una interfaz, también puede configurar 192.168.1.11, si nadie más en la red lo está utilizando) , y en esos casos podría tener aplicaciones separadas para escuchar en el puerto 8000 en cada una de esas dos direcciones IP.

Si por aplicaciones te refieres a procesos múltiples, entonces sí, pero generalmente NO. Por ejemplo, el servidor Apache ejecuta múltiples procesos en el mismo puerto (generalmente 80). Se hace designando uno de los procesos para vincularse realmente al puerto y luego usar ese proceso para hacer transferencias a varios procesos que aceptan conexiones.

Puede hacer que dos aplicaciones escuchen el mismo puerto en la misma interfaz de red.

Solo puede haber un socket de escucha para la interfaz de red y el puerto especificados, pero ese socket se puede compartir entre varias aplicaciones.

Si tiene un socket de escucha en un proceso de aplicación y fork ese proceso, el socket se heredará, por lo que técnicamente ahora habrá dos procesos escuchando el mismo puerto.

He intentado lo siguiente, con socat :

 socat TCP-L:8080,fork,reuseaddr - 

Y aunque no he hecho una conexión con el socket, no puedo escuchar dos veces en el mismo puerto, a pesar de la opción reuseaddr .

Recibo este mensaje (que esperaba antes):

 2016/02/23 09:56:49 socat[2667] E bind(5, {AF=2 0.0.0.0:8080}, 16): Address already in use 

Respuesta corta:

Siguiendo la respuesta dada aquí . Puede tener dos aplicaciones escuchando en la misma dirección IP y número de puerto, siempre que uno de los puertos sea un puerto UDP, mientras que el otro sea un puerto TCP.

Explicación:

El concepto de puerto es relevante en la capa de transporte de la stack TCP / IP, por lo tanto, siempre que utilice diferentes protocolos de capa de transporte de la stack, puede tener múltiples procesos escuchando en la misma : combinación.

Una duda que tienen las personas es si dos aplicaciones se ejecutan en la misma combinación de : , ¿cómo distinguirá un cliente que se ejecuta en una máquina remota entre las dos? Si observa el encabezado del paquete de la capa IP ( https://en.wikipedia.org/wiki/IPv4#Header ), verá que los bits 72 a 79 se usan para definir el protocolo, así es como se puede hacer la distinción.

Sin embargo, si desea tener dos aplicaciones en la misma combinación de TCP : , la respuesta es no (un ejercicio interesante será iniciar dos máquinas virtuales, darles la misma dirección IP, pero direcciones MAC diferentes, y ver lo que sucede, notará que algunas veces VM1 obtendrá paquetes, y otras veces VM2 obtendrá paquetes, dependiendo de la actualización del caché ARP.

Siento que haciendo que dos aplicaciones se ejecuten en la misma : desea lograr algún tipo de equilibrio de carga. Para esto, puede ejecutar las aplicaciones en diferentes puertos y escribir reglas de tabla de IP para bifurcar el tráfico entre ellas.

También vea la respuesta de @ user6169806.