내 집 데스크탑의 가상 머신에 웹 서버를 설정했습니다. 라우터에서 여러 포트(80, 443 등)를 데스크탑으로 전달한 후 NAT를 통해 가상 머신으로 전달합니다(참조:도표예시용). 이것은 간단한 아파치 서버를 실행할 때 잘 작동하는 것 같습니다. 그러나 WebSocket을 사용하려고 할 때 문제가 발생합니다.
간단한 WebSocket 에코 서버를 설정했습니다(다음에서 정확히 복사됨).https://www.boost.org/doc/libs/master/libs/beast/example/websocket/server/async-ssl/websocket_server_async_ssl.cpp물론 SSL 인증서를 내 것으로 변경하는 것을 제외하고) 포트 6164에서 수신 대기한 다음 다른 인증서와 동일한 방식으로 전달합니다. 또한 앞서 언급한 Apache 서버에서 호스팅되는 간단한 웹 페이지(참조용 아래 코드)를 설정하여 서버에 대한 웹 소켓을 열고 메시지를 보냅니다.
서버가 의도한 대로 정확하게 작동하는 것 같습니다. WebSocket 연결을 열고 다시 에코되는 메시지를 보낼 수 있습니다. 그러나 로컬 컴퓨터(또는 다른 장치)에서 WebSocket을 열 때마다 네트워크, 그것언제나양쪽에서 포트 6164를 사용하므로 로컬 네트워크에서 한 번에 하나의 연결만 발생할 수 있습니다. 내 로컬 네트워크 외부의 장치에서 시작되는 연결의 경우에는 해당되지 않으며 클라이언트 측의 임시 포트를 사용합니다. (보다포트 분석 다이어그램테스트된 경우).
- 왜 이런 일이 발생합니까?
- 전체 경로를 따라 연결에 어떤 일이 일어나고 있는지 추적하는 데 사용할 수 있는 도구가 있습니까? (즉, 어떤 IP/포트를 통해 전달됩니까?)
- 나는 네트워킹에 익숙하지 않기 때문에 어쨌든 클라이언트 포트를 결정하는 것은 무엇입니까? 브라우저 자체가 하나를 선택하는 것일까요?
약간의 추가 정보: netstat를 확인하면 리스너에 다음이 표시됩니다.
tcp 0 0 0.0.0.0:6164 0.0.0.0:* 듣기 26866/./serv...
내 네트워크에 있는 컴퓨터(또는 내 휴대폰)가 연결되면 다음이 표시됩니다.
tcp 0 0 10.0.2.15:6164 10.0.2.2:6164 설정됨 26866/./serv...
하지만 네트워크에서 휴대폰 연결을 끊고 데이터를 사용하거나 로컬 네트워크에 없는 컴퓨터를 사용하면 다음과 같은 내용이 표시됩니다.
tcp 0 0 10.0.2.15:6164 10.0.2.2:51616 설정됨 26866/./serv...
여기서 51616 임시 포트 번호는 매번 변경됩니다. 10.0.2.15는 내 VM의 IP이고 10.0.2.2는 VM의 게이트웨이입니다.
또한 이는 포트 6164에만 해당되는 것이 아니기 때문에 서버가 다른 여러 포트에서 수신 대기하도록 하여 ws = new WebSocket("wss://shaun.ralsum.com:6164");
이에 따라 코드 줄을 변경해 보았지만 결과는 동일했습니다.
편집하다:여기다음은 user1686이 요청한 라우터->데스크톱(왼쪽) 및 데스크톱->VM(오른쪽)에 대한 포트 전달 규칙의 이미지입니다.
웹페이지 코드
<!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>
참고: 원래는 스택 오버플로에 게시되었지만 대신 여기에 게시하는 것이 좋습니다.