Todas las conexiones WebSocket que se originan en la red local utilizan el mismo puerto del lado del cliente (en lugar de efímero) cuando se conectan al servidor web local. ¿Por qué?

Todas las conexiones WebSocket que se originan en la red local utilizan el mismo puerto del lado del cliente (en lugar de efímero) cuando se conectan al servidor web local. ¿Por qué?

Configuré un servidor web en una máquina virtual en el escritorio de mi casa. Hago que mi enrutador reenvíe varios puertos (80, 443, etc.) a mi escritorio, y luego los reenvía vía NAT a la máquina virtual (consultediagramapor ilustracion). Esto parece funcionar bien cuando se ejecuta un servidor Apache simple. Sin embargo, encuentro problemas al intentar utilizar WebSockets.

Configuré un servidor de eco WebSocket simple (copiado exactamente dehttps://www.boost.org/doc/libs/master/libs/beast/example/websocket/server/async-ssl/websocket_server_async_ssl.cppexcepto, por supuesto, cambiar los certificados SSL para que sean míos) para escuchar en el puerto 6164, que luego también reenvío de la misma manera que los demás. También configuré una página web simple (código a continuación como referencia) alojada en el servidor Apache que mencioné antes para abrir un websocket al servidor y enviar un mensaje.

El servidor parece funcionar exactamente como estaba previsto, puedo abrir una conexión WebSocket y enviar un mensaje que se repite, etc. Sin embargo, he notado que cada vez que abro WebSocket desde una computadora (u otro dispositivo) en mi local red, essiempreutiliza el puerto 6164 en ambos lados y, por lo tanto, solo puede realizarse una conexión desde mi red local a la vez. Este no es el caso de las conexiones que se originan desde dispositivos fuera de mi red local, utilizan puertos efímeros en el lado del cliente. (Verdiagrama de desglose de puertospara casos probados).

  1. ¿Por qué está pasando esto?
  2. ¿Existen herramientas que pueda utilizar para rastrear lo que le sucede a la conexión en todo su recorrido? (Es decir, a través de qué IP/puertos se reenvía)
  3. Como soy bastante nuevo en el ámbito de las redes: ¿qué determina el puerto del cliente de todos modos? ¿Es sólo el propio navegador eligiendo uno?

Un poco de información adicional: cuando reviso netstat, el oyente muestra

tcp 0 0 0.0.0.0:6164 0.0.0.0:* ESCUCHAR 26866/./serv...

y cuando cualquier computadora (o mi teléfono) en mi red está conectada, muestra

tcp 0 0 10.0.2.15:6164 10.0.2.2:6164 ESTABLECIDO 26866/./serv...

pero cuando desconecto mi teléfono de mi red y uso datos, o uso una computadora que no está en mi red local, se lee

tcp 0 0 10.0.2.15:6164 10.0.2.2:51616 ESTABLECIDO 26866/./serv...

donde el número de puerto efímero 51616 cambia cada vez. 10.0.2.15 es la IP de mi VM, 10.0.2.2 es la puerta de enlace de la VM.

Además, esto no es exclusivo del puerto 6164. Intenté que el servidor escuchara en varios otros puertos y cambié la ws = new WebSocket("wss://shaun.ralsum.com:6164");línea del código en consecuencia, con el mismo resultado.

Editar:AquíEs una imagen de mis reglas de reenvío de puertos para enrutador->Escritorio (izquierda) y Escritorio->VM (derecha) según lo solicitado por el usuario1686.


código de página web

<!DOCTYPE HTML>

<html>
  <head>
    
    <script>
      function openConnection(){
      if(window.WebSocket){
          // Open a web socket
          ws = new WebSocket("wss://shaun.ralsum.com:6164");
          ws.onopen = function(){
          ws.send("socket open");
          document.getElementById('socketStatus').innerHTML =
              "socket connected";
          };
          ws.onmessage = function(evt){
          var recievedMessage = evt.data;
          document.getElementById('serverResponse').innerHTML =
              recievedMessage;
          };
      } else{
          document.getElementById('socketStatus').innerHTML =
          "WebSockets not supported";
      }
      }

      function sendMessage(){
      // use global web socket object to send a message
      ws.send("sending another message");
      }
      
      function closeConnection(){
      // close the web socket connection
      ws.close();
      document.getElementById('socketStatus').innerHTML =
          "socket disconnected";
      }
    </script>
    
  </head>
  
  <body>
    <p id="socketStatus">socket disconnected</p>
    <button onclick="openConnection()">create socket</button>
    <button onclick="sendMessage()">send message</button>
    <button onclick="closeConnection()">close socket</button>
    <p id="serverResponse">response from server</p>
  </body>
  
</html>

Nota: publicado originalmente en desbordamiento de pila, pero se recomendó publicarlo aquí.

información relacionada