C / C ++ 멀티 플레이어 게임의 네트워크 메시지를 직렬화 및 직렬화 해제하는 가장 좋은 방법은 무엇입니까?


11

현재 JSON을 사용하고 있으며 클라이언트와 서버 간의 일부 유형의 메시지에 대해 이진 형식으로 이동하려고합니다.

소켓으로 구조체를 읽어야합니까? 프로 티콜 버퍼 / 스 리프트를 사용하십니까?

데이터 배열을 어떻게 표현해야합니까?

데이터 패킹 / 언 패킹에 대한 인터페이스는 어떤 모습입니까?

답변:


12

가정 ...

  1. 바이트 버퍼로 변환하는 것에 대해 이야기하고 있습니다.
  2. UDP를 사용하고 있으며 성능이 문제입니다

구조를 정의하기 위해 패킷에 공간을 낭비하지 마십시오. IE는 최소한 패킷 유형을 나타내는 바이트를 보낸 다음 수신 된 각 패킷이 해당 유형의 패킷에 대해 사전 정의 된 구조를 따른다고 가정합니다.

소켓으로 구조체를 읽어야합니까? 프로 티콜 버퍼 / 스 리프트를 사용하십니까?

  • 예, 전체 구조가 필요한 경우 전체 구조를 읽으십시오.
  • 아니요, 패킷 구조를 직접 만드십시오.이 방법을 사용하는 직렬화보다 확실히 작습니다. 패킷에 어떤 데이터가 포함되어야하는지 정확히 알아야합니다

데이터 배열을 어떻게 표현해야합니까?

  • 데이터 배열로. 수신 할 때 배열 요소의 개수를 보내지 않도록 데이터 끝까지 버퍼를 계속 읽습니다.

데이터 패킹 / 언 패킹에 대한 인터페이스는 어떤 모습입니까?

  • 기본 유형을 바이트로 변환하는 많은 메소드를 쉽게 설정할 수 있습니다.이 메소드에서 사용자 정의 유형을 변환하는 빌드도 있습니다. 이 작업을 수행 하는 방법대한 자세한 내용은 거의 모든 곳에서 찾을 수 있습니다 (개인적으로 C #을 사용합니다)

마지막으로, 패킷 크기 특히 스냅 샷에서 중요합니다. size = packetSize x 엔티티 x connectedPlayers; 따라서 패킷 당 60 x 10 x 16 = 9,600 바이트를 가질 수 있습니다. 그런 다음 초당 20 번 전송합니다 : = 192,000bps = 187KBps. 이것은 업로드 속도가 높은 밴드입니다. 따라서 가능한 경우 패킷 크기에 기여하는 각 요소를 최소화해야합니다.

이 문서에서는 대단히 도움이되었습니다 : 밸브 멀티 네트워킹


다양한 객체 직렬화를 읽고 여기에 질문을 네트워킹하는 동안 발견 한 또 다른 기사는 몇 주 전 이 하나의 언리얼 엔진을 수행하는 방법에 대해 설명합니다. 밸브 소스에 대한 좋은 비교 포인트.
Martin Foot

1
일반적인 경우 배열 방법이 작동하지 않습니다. '데이터 끝'은 어디에 있습니까? 메시지가 구분되어 있어도 구조체 당 하나 이상의 배열을 가질 수 없습니다. 이 문제를 해결하기 위해 원래 포스터는 고정 길이 배열을 고수하거나 구조체 당 하나의 배열 만 (구조의 끝에) 있는지 확인하거나 배열 시작시 카운트 값을 보낼 수 있습니다.
Kylotan

팁 하나만 더 : 엔디안을 치료하는 것을 잊지 마십시오. 그러한 것이 존재한다는 것을 모르면 매우 성 가실 수 있습니다.

좋은 지적 @Kylotan, 경우에 따라 이러한 추가 데이터를 피할 수 없다는 데 동의합니다. 그러나 하나의 패킷에 여러 배열을 추가하는 것을 발견하면 대신 여러 패킷을 보내는 것이 좋습니다
실제로 005

1

이 문제는 Google과 Facebook에서 해결되었습니다.

  1. Google의 프로토콜 버퍼 — Google은 C ++을 많이 사용합니다.

    프로토콜 버퍼는 구조적 데이터를 효율적이지만 확장 가능한 형식으로 인코딩하는 방법입니다. Google은 거의 모든 내부 RPC 프로토콜 및 파일 형식에 프로토콜 버퍼를 사용합니다.

  2. Apache Thrift (이전의 Facebook) :

    Thrift는 확장 가능한 언어 간 서비스 개발을위한 소프트웨어 프레임 워크입니다. 소프트웨어 스택과 코드 생성 엔진을 결합하여 C ++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C #, Cocoa, JavaScript, Node.js, Smalltalk 및 OCaml간에 효율적으로 원활하게 작동하는 서비스를 빌드합니다.


Google 프로토콜 버퍼는 대규모 실시간 게임에 비해 너무 느립니다. 그러나 버전 관리 때문에 프로토 타이핑과 더 적은 플레이어 수에 아주 좋은 것으로 나타났습니다. 평소와 같이 프로파일 러가 실제 이야기를 들려줍니다.
Patrick Hughes

글쎄, 그들은 구글에 충분하고 구글은 꽤 잘 확장되며 내가 그들을 사용할 때 잘 작동했습니다. 그래서 나는 그들을 추천했습니다.
유료 괴상한

Google은 실시간 성능을 요구하지 않습니다. Google은 안정성과 가동 시간이 필요하며 둘 다 프로토콜 버퍼에 의해 잘 제공됩니다. 대체 버전 관리 및 상용구 코드 생성의 복잡성으로 인해 오버 헤드가 발생하고 50-100msec 간격으로 1000 개의 업데이트를 보내고받을 때 추가됩니다. 현재 데이터와 관련된 코딩 된 시리얼 라이저에 대해 여러 버전의 프로토콜 버퍼를 프로파일 링하십시오. @ indeed005에는 요점이 있습니다.
Patrick Hughes

+1. 이러한 형식은 대부분의 실시간 또는 고 대역폭 게임 (임의로 복잡한 패킷을 재구성 할 수있는 추가 정보가 포함되어 있기 때문에)에 비해 너무 크고 느리지 만, 유용하지 않다고 말할 수는 없습니다. 일부 게임, 예. 턴제 것들. 모든 리소스를 최적화 할 필요가없는 경우 이러한 형식을 사용하면 많은 시간을 절약 할 수 있으며 JSON보다 확실히 더 효율적입니다.
Kylotan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.