UDP를 사용한 승인 신뢰성


16

UDP에 대한 질문이 있습니다. 맥락 상, 저는 실시간 액션 게임을하고 있습니다.

나는 UDP와 TCP의 차이점에 대해 꽤 많이 읽었으며 그것들을 아주 잘 이해한다고 생각하지만 결코 정확하지 않은 한 부분이 있으며 신뢰성 과 구체적으로 인정 합니다. UDP는 기본적으로 안정성을 제공하지 않는다는 것을 이해합니다 (즉, 패킷이 삭제되거나 순서가 잘못 될 수 있음). 신뢰성이 필요한 경우, 내가 본 솔루션 (개념적으로 의미가있는)은 승인을 사용하는 것입니다 (예 : 서버가 클라이언트에게 패킷을 보내고 클라이언트가 해당 메시지를 수신하면 서버에 승인을 다시 보냅니다) .

승인이 삭제되면 어떻게됩니까?

위의 예 (한 서버가 한 클라이언트에게 패킷을 보내는 경우)에서 서버는 해당 패킷에 대한 승인이 수신 될 때까지 매 프레임마다 패킷을 재전송함으로써 잠재적 인 패킷 손실을 처리합니다. 여전히 대역폭 또는 비 순차적 메시지 문제가 발생할 수 있지만 순전히 패킷 손실 측면에서 서버가 적용됩니다.

그러나 클라이언트가 도착하지 않은 승인을 보내면 서버는 해당 메시지의 전송을 중단 할 수밖에 없습니다. 따라서 해당 패킷에 포함 된 정보가 필요한 경우 게임이 중단 될 수 있습니다. 서버에 대한 비슷한 접근 방식을 취할 수 있습니다 (즉, ack에 대한 애크가 수신 될 때까지 수신 확인을 계속 보내시겠습니까?).하지만 그 접근 방식은 ack에 대한 ack에 대한 애크가 필요하기 때문에 영원히 반복됩니다. 등등).

내 기본 논리가 여기에 맞다고 생각합니다. 두 가지 옵션이 있습니다.

  1. 단일 승인 패킷을 보내고 최선을 다하겠습니다.
  2. 소수의 승인 패킷 (아마 3-4 개)을 보내고 모든 패킷이 삭제되지는 않는다는 가정하에 최선을 다하겠습니다.

이 문제에 대한 답변이 있습니까? 내가 근본적으로 오해하고 있습니까? 내가 모르는 UDP 사용에 대한 보증이 있습니까? 내 논리가 튼튼하다고 느낄 때까지 너무 많은 네트워킹 코드를 사용하는 것이 주저합니다.


11
"시간 초과"및 "재시도"에 대한 아이디어가 누락되었을 수 있습니다.
크롬 스터, 모니카

아마 그래요 당신은 내 논리가 정확하고 너무 부정적으로 들리지 않는다고 제안하지만 네트워크 프로그래밍 중에는 거의 모든 네트워크 정보에 대해 보장 할 수 없다고 가정합니까? 실시간 게임을 진행하는 동안 많은 정보가 손실 될 수 있지만 문제를 이해하고 싶습니다.
Grimelios 2016 년

10
전혀 보장하지 않습니다. 권리. 알고리즘에 "희망"을 포함시키지 마십시오. 그들은 운이 나쁜 조합을 처리해야합니다. PS 우리는 RTS에서 TCP로 간단히 전환했습니다. 신뢰할 수있는 통신 (록 스텝 시뮬레이션을 위해)이 필요하기 때문에 eberything이 처리됩니다.
크롬 스터, 모니카

5
신뢰성이 필요한 경우 TCP를 사용하고 중요하지 않은 경우 UDP를 사용하십시오. 예를 들어 플레이어의 좌표는 내 게임에서 UDP를 통해 전송됩니다. 보간 및 스무딩을 사용하여 누락 된 패킷을 스무딩합니다. 매력처럼 작동합니다. 실제로 신뢰할 수 있어야하지만 조금 느려질 수있는 것은 TCP를 통해 전송됩니다. 새로운 상태가 오래된 상태를 무효화하는 상태가있는 경우 UDP는 사이에 무언가가 떨어졌을 때 중요하지 않기 때문에 좋은 선택입니다. 선수 위치).
Polygnome

이것은 귀하의 질문에 대한 직접적인 대답은 아니지만 실시간 게임이 꼭 필요한 경우 (예 : 초기 연결)에만 승인을 요구하는 것이 좋습니다. 가능한 경우 상태 비 저장 시스템에서 새 패킷을 얻을 때까지 클라이언트와 서버를 모두 설계하여 훨씬 더 간단하고 강력하게 설계 할 수 있습니다. Quake 3는 스냅 샷 기반 시스템에서이 작업을 매우 잘 수행했습니다 . 또한 Enet과 같은 라이브러리는 실제로 필요할 때 특정 패킷 만 안정적으로 전송할 수 있습니다.
jrh

답변:


32

이것은 두 가지 일반 문제 의 한 형태이며, 옳습니다. 재시도 횟수만으로도 완벽하게 영수증을받을 수 있습니다.

실제로 게임에서는 정보가 기술적으로 안정적으로 도착하더라도 정보가 실제로 중요하지 않은 시간대가 있습니다. 2 초 전에 정렬 된 완벽한 헤드 샷을 발견 한 것처럼 플레이어가 해당 정보를 사용하기에는 너무 늦습니다.

패킷 손실이 너무 커서 긴밀한 반응 창 내에서 필요한 정보를 정기적으로 얻을 수 없다면 실시간 게임의 경우 플레이어를 쫓아 내고 다른 곳에서보다 더 나은 경기를 찾는 것이 좋습니다. 안정적인 연결을 에뮬레이트하기 위해 패킷을 계속 보내려고합니다.

이로 인해 일부 게임 복제 시스템은 승인 및 재 시도를 모두 건너 뛰고 최대한 자주 최신 업데이트를 스팸으로 분류합니다. 하나가 떨어지거나 늦게 도착하거나 너무 늦게 도착하면 건너 뛰고 다음 단계를 수행하여 예측 및 보간 시스템에 의존하여 간격을 매끄럽게하고 플레이어가 볼 수있는 딸꾹질을 최소화하십시오.

나는 과거의 문제를 무시하고 현재에 살아가는 방법에 대해이 "Simba Replication"이라고 부르기 시작했다. ;)

Rafiki는 그 삶의 철학에 대해 reductio ad absurdum을 내려 놓았습니다.

하이브리드 솔루션은 새로운 업데이트를 전송하고 (게임 상태 업데이트는 종종 매우 작거나 압축 가능하기 때문에 ) 마지막 업데이트와 그 이전의 업데이트를 포장하는 것입니다. 따라서 클라이언트가 누락 된 경우를 대비하여 왕복 여행 시간을 기다릴 필요가 없습니다. 대부분의 경우 클라이언트는 이미 이것을 보았으므로 이런 식으로 중복 데이터가 있지만 누락 된 메시지를 수정하기위한 대기 시간은 더 짧습니다. 클라이언트 업데이트에는 최근에 본 연속 업데이트의 인덱스 번호가 포함될 수 있으므로 다음 업데이트 패킷에 포함 된 이전 업데이트 수를 최소화 할 수 있습니다.

또 다른 유형의 하이브리드로 2 계층 시스템을 구현할 수도 있습니다. 여기서 단기 수명은 신뢰할 수없는 빠른 실행 방식으로 복제되고 TCP 또는 자체 재 시도를 통해 자체 안정성 구현을 사용하여 장기 상태를 안정적으로 동기화합니다. 카운트. 관리 할 메시징 시스템이 두 개이고 스냅 샷이 서로 동기화되지 않아 완전히 새로운 클래스의 엣지 케이스가 추가되기 때문에 관리가 더 복잡해집니다.


1
+1, 잘 작성되었습니다. 나는 이것이 액션 / 실시간 게임과 더 관련이 있다는 것을 강조하고 싶습니다. TBS 및 RTS 게임 (및 일부 액션 게임의 이벤트)은 "정보가 실제로 중요하지 않은 시간 지평"에 대해 다른 견해를 가지고 있습니다.
Kromster는 Monica

3
예, 턴 기반 게임의 경우 UDP 위에 자체 안정성 계층을 롤링하는 대신 TCP를 사용한다고 상상할 수 있습니다. ;) 그래도 RTS에서 마이크로는 여전히 정확한 시간 지평을 가진 게임 플레이의 유형으로 분류하고 있습니다. 하이브리드 접근법은 잘 작동 할 수 있습니다. 여기서 순간의 열에 대한 지연 시간이 짧은 업데이트와 자원 지출과 같은 중요한 누락 된 이벤트를 소급하여 처리 할 수있는 안전망.
DMGregory

그것은 매우 도움이되고 내 초기 관심사를 확인합니다. 대단히 감사합니다.
Grimelios 2016 년

2
Forward Error Correction을 언급하는 것이 유용 할 수도 있습니다. 수신자가 다음 패킷을 수신 할 때 패킷이 손실되었음을 독립적으로 파악하여 필요한 보간을 부드럽게하기 위해 추가 데이터를 추가 할 수 있도록 프로토콜을 설계하십시오. 이것은 종종 UDP 패킷이 가득 차 있지 않기 때문에 유용하며 대기 시간을 줄이기 위해 더 작은 패킷을 더 자주 보냅니다. 여분의 바이트를 추가해도 대기 시간이 손상되지 않으며 대역폭은 문제가되지 않습니다.
MSalters 2012 년

@MSalters 나는 당신이 그것을 원한다면 그 자체의 답변으로 정교하게 가치가 있다고 말하고 싶습니다. 나는 그것을 찬성했다. :)
DMGregory

9

TCP가 사용하는 접근 방식은 보낸 사람이 승인을받을 때까지 패킷을 계속 다시 보내는 것입니다. 수신자는 중복 패킷을 무시하지만 여전히 승인을 보냅니다. 발신자는 중복 승인을 무시합니다.

패킷이 손실되면 이미 알고 있듯이 발신자가 다시 보냅니다.
수신 확인이 유실되면 송신자는 원래 패킷을 재전송하여 수신자가 수신 확인을 재전송합니다.

일정 시간 (60 초 또는 20 번의 재시도) 내에 승인을받지 못하면 플레이어는 게임에서 연결이 끊어진 것으로 간주됩니다. 당신은 해야한다 시간 제한 규칙 또는 기타 네트워크 케이블이 영원히 서버의 리소스를 묶어 것이다 언 플러그 선수의 어떤 종류를 구현합니다.


TCP의 필수 기능은 보낸 사람이 특정 패킷이 확인 되었는지 여부를 신경 쓰지 않아도 되지만 대부분 "높은 워터 마크"와 높은 워터 마크 이동없이 패킷이 얼마나 오래 걸렸는지를 신경 써야한다는 것입니다.
supercat

1
@ supercat 나는 그것이 필수적이라고 말하지 않을 것입니다. 더 최적화처럼.
user253751 2016 년

괄호 안에있는 것 (이미 얻은 패킷에 대해 ACK를 보내는 것)에 대해서는 괄호 대신 실제로 강조해야한다고 생각합니다. OP의 이해 (또는 적어도 설명)에서 누락 된 것 같습니다.
Angew는 더 이상 SO

@Angew가 완료했습니다.
user253751

6

TCP를 재발 명하려는 경우 TCP를 먼저 살펴보면 설명하는 정확한 문제를 해결할 수 있습니다 (솔루션의 일부는 재시도 및 시간 초과에 사용자 정의 값을 사용하는 것임).

2 개의 채널, 안정적인 통신을위한 TCP 채널 및 짧은 대기 시간을위한 UDP 채널을 사용하는 솔루션은 드문 일이 아닙니다.

일부 솔루션은 클라이언트에 정보가 너무 오랫동안 누락 된 것을 감지하고 UDP 또는 TCP를 사용하는 재 동기화를 시작합니다.

또 다른 일반적인 접근 방식은 커뮤니케이션을 디자인하여 승인에 전혀 의존하지 않지만 질문의 범위를 벗어납니다.


3

RTS에서는 실제로 TCP와 같은 프로토콜을 사용할 수 없으며 UDP도 신뢰할 수 없습니다. 시도하면 네트워크에 문제가 생길 때마다 게임이 정지됩니다.

대신, 누락 된 패킷이 그다지 중요하지 않도록 프로토콜을 설계합니다.

짧은 버전은 다른 플레이어가 현재 위치를 알고있는 한 마지막 프레임의 위치를 ​​신경 쓰지 않는다는 것 입니다. 긴 버전은 더 복잡합니다.

그러면 패킷이 없어지면 어떻게해야합니까? 그리고 대답은 ... 당신은 추측합니다. 플레이어는 아마도 직선으로 움직일 것입니다. 해당 라인을 따라 한 단계 더 이동하십시오. ... RTS 플레이어 직선 으로 움직이지 않는 것을 제외하고 . 그리고 충돌 감지가 있습니다.

이것은 어렵다. 많은 게임들이 잘못합니다. 더가 없음을 주장 할 수있는 권리 이에 대한 대답, 절충 할 수 있습니다 만 여러 가지 잘못이.

이 게임들이 잘 작동하는 이유는 그들이이 문제들에 대해 오랫동안 열심히 생각했을뿐만 아니라 인터넷이 상당히 신뢰할 수있게 되었기 때문입니다. 거의 모든 UDP 패킷은 실제로 적시에 목적지에 도달합니다. (방화벽과 같은 영구적 인 문제가 없다면)


워크래프트 3은 TCP를 사용합니다.
fsp
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.