2012-03-02 3 views
0

현재 클라이언트에서 로그인 할 수있는 UDP 응용 프로그램을 프로그래밍 중입니다. 그 다음에는 엔드 포인트가 목록에 저장됩니다.UDP 및 포트 랜덤 화

private void socket_Callback(IAsyncResult result_) 
{ 
    EndPoint remote = new IPEndPoint(IPAddress.Any, 0); 
    socket.EndReceiveFrom(result_, ref remote); 

    if (!listOfEndPoints.Contains(remote)) 
    { 
     // registration process 

     // add it to list 
     listOfEndPoints.Add(remote) 
    } 
    else 
    { 
     // process packet 
    } 
} 

그러나 클라이언트의 NAT는 모든 패킷에 다른 외부 종점을 할당하기도합니다. 등록 패킷의 소스 끝 점이 12.34.56.78:1000이면 해당 끝점이 목록에 추가됩니다. 그러나 동일한 클라이언트가 다른 패킷을 보내면 NAT가 다른 포트를 할당하므로 소스 끝 점이 12.34.56.78:1001이됩니다. 이 결과로 서버는 클라이언트가 등록되지 않았다고 가정하고 패킷을 등록 된 것으로 처리하려고합니다. 말할 필요도없이 작동하지 않습니다.

이 문제를 해결하는 방법은 ID를 전송하는 것입니다 (그러나 매우 신빙성이 없다면 쉽게 위장 할 수 있습니다). 그러나 클라이언트는 서버에 보내는 각 패킷에이를 추가해야합니다. 이렇게 그렇게하는 것은 그리 효과적이지 않을 것입니다.

패킷이 등록 패킷과 동일한 클라이언트에서 왔음을 알리는 다른 방법이 있습니까?

답변

3

아니요 UDP 패킷의 원본 IP 주소와 포트를 사용하여 논리적 연결과 연결해야합니다. 각 패킷에 연결 ID를 포함하고 동일한 논리 연결에 대해 새 IP 및 포트를 수신 한 경우 응답하는 IP 및 포트를 업데이트해야합니다. 연결 하이킹이 문제가되는 경우 데이터 그램에 보안 체크섬과 같은 보안을 구현해야 할 수 있습니다.

TCP는 패킷을 연결로 연결합니다. UDP를 사용하면 데이터 그램을 논리적 세션과 직접 연관시켜야합니다. 나는 왜 그런 식으로하지 않는 것이 좋을지 모르겠다.

UDP의 단점 중 하나는 TCP가 제공해야 할 것이 있으면 직접 코딩해야한다는 것입니다.

그런데 이처럼 포트가 이동하는 것을 본 적이 없습니다. 클라이언트 코드가 깨지지 않았는지 확인하십시오. 아마도 송신하는 각 데이터 그램에 대해 새 소켓을 여는 것이 좋습니다.

+0

감사합니다. 내 코드의 버그 인 경우 왜 패킷의 끝점을 사용하지 않아야합니까? 그것은 모든 고객에게 그다지 독특하지 않겠습니까? 그리고 보안 체크섬은 어떻게 생겼을까요? 등록 할 때 클라이언트에게 임의의 번호를 보내는 것에 대해 생각하고있었습니다. 클라이언트는 패킷에 md5 (패킷 데이터 XOR 체크섬)를 추가합니다. 그런 다음 서버는 체크섬의 정확성을 검사합니다. 그게 당신이 의미하는 바 였나요? – haiyyu

+1

@haiyyu : 엔드 포인트 데이터를 사용하지 않는 이유는 상대방의 IP 주소가 변경 될 수 있기 때문입니다. TCP를 사용하면 네트워크가 패킷을 세션과 연관시켜야하며 NAT 장치는 IP를 보존해야한다는 것을 알고 있습니다. UDP에서는 그렇지 않습니다. 그리고 네, 그것이 제가 의미하는 것입니다. 물론 최상의 솔루션은 요구 사항에 따라 다릅니다. –