WebSocket-Verbindungen, die aus dem lokalen Netzwerk stammen, verwenden beim Herstellen einer Verbindung zum lokalen Webserver alle denselben clientseitigen Port (anstelle des temporären). – Warum?

WebSocket-Verbindungen, die aus dem lokalen Netzwerk stammen, verwenden beim Herstellen einer Verbindung zum lokalen Webserver alle denselben clientseitigen Port (anstelle des temporären). – Warum?

Ich habe einen Webserver auf einer virtuellen Maschine auf meinem Desktop zu Hause eingerichtet. Mein Router leitet mehrere Ports (80, 443 usw.) an meinen Desktop weiter und leitet sie dann über NAT an die virtuelle Maschine weiter (sieheDiagrammzur Veranschaulichung). Dies scheint beim Betrieb eines einfachen Apache-Servers problemlos zu funktionieren. Beim Versuch, WebSockets zu verwenden, treten jedoch Probleme auf.

Ich habe einen einfachen WebSocket Echo-Server eingerichtet (genau kopiert vonhttps://www.boost.org/doc/libs/master/libs/beast/example/websocket/server/async-ssl/websocket_server_async_ssl.cppaußer natürlich, dass ich die SSL-Zertifikate so ändere, dass sie meine eigenen sind), um auf Port 6164 zu lauschen, den ich dann auch auf die gleiche Weise weiterleite wie die anderen. Ich habe auch eine einfache Webseite eingerichtet (Code unten als Referenz), die auf dem zuvor erwähnten Apache-Server gehostet wird, um einen Websocket zum Server zu öffnen und eine Nachricht zu senden.

Der Server scheint genau wie vorgesehen zu funktionieren. Ich kann eine WebSocket-Verbindung öffnen und eine Nachricht senden, die zurückgesendet wird usw. Allerdings habe ich festgestellt, dass jedes Mal, wenn ich den WebSocket von einem Computer (oder einem anderen Gerät) in meinem lokalen Netzwerk öffne,stetsverwendet Port 6164 auf beiden Seiten, und daher kann nur eine Verbindung aus meinem lokalen Netzwerk gleichzeitig erfolgen. Dies ist nicht der Fall für Verbindungen, die von Geräten außerhalb meines lokalen Netzwerks stammen, diese verwenden temporäre Ports auf der Clientseite. (SieheHafenaufschlüsselungsdiagrammfür getestete Fälle).

  1. Warum passiert das?
  2. Gibt es Tools, mit denen ich nachverfolgen kann, was mit der Verbindung auf ihrem gesamten Pfad geschieht? (D. h. über welche IPs/Ports wird sie weitergeleitet)
  3. Da ich mich mit Netzwerken noch nicht so gut auskenne: Wodurch wird überhaupt der Port des Clients bestimmt? Wählt der Browser selbst einen aus?

Eine kleine Zusatzinformation: wenn ich netstat überprüfe, zeigt der Listener

tcp 0 0 0.0.0.0:6164 0.0.0.0:* LISTEN 26866/./serv…

und wenn ein beliebiger Computer (oder mein Telefon) in meinem Netzwerk verbunden ist, wird angezeigt

tcp 0 0 10.0.2.15:6164 10.0.2.2:6164 HERGESTELLT 26866/./serv…

aber wenn ich mein Telefon von meinem Netzwerk trenne und Daten verwende oder einen Computer verwende, der nicht in meinem lokalen Netzwerk ist, wird angezeigt

tcp 0 0 10.0.2.15:6164 10.0.2.2:51616 HERGESTELLT 26866/./serv…

wobei sich die flüchtige Portnummer 51616 jedes Mal ändert. 10.0.2.15 ist die IP meiner VM, 10.0.2.2 ist das Gateway der VM.

Darüber hinaus ist dies nicht nur auf Port 6164 beschränkt. Ich habe versucht, den Server auf mehreren anderen Ports lauschen zu lassen und die ws = new WebSocket("wss://shaun.ralsum.com:6164");Zeile im Code entsprechend zu ändern, mit demselben Ergebnis.

Bearbeiten:Hierist ein Bild meiner Portweiterleitungsregeln für Router->Desktop (links) und Desktop->VM (rechts), wie von Benutzer1686 angefordert.


Webseitencode

<!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>

Hinweis: Ursprünglich auf Stack Overflow gepostet, aber es wurde empfohlen, stattdessen hier zu posten.

verwandte Informationen