Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

개발자공부일기

패킷 길이문제 본문

트러블슈팅

패킷 길이문제

JavaCPP 2025. 1. 16. 20:34

 

버퍼객체를 주고받는 테스트를 하던 와중 이런 오류들이 클라이언트(unity)에서 발생했다. 뭐라는지 알아보자

 

Deserialize: Failed to deserialize data. Exception: System.IO.EndOfStreamException: Attempted to read past the end of the stream.
  at ProtoBuf.ProtoReader+State.ThrowEoF () [0x00000] in /_/src/protobuf-net.Core/ProtoReader.State.ReadMethods.cs:809 
  at ProtoBuf.ProtoReader+StreamProtoReader.Ensure (ProtoBuf.ProtoReader+State& state, System.Int32 count, System.Boolean strict) [0x00106] in /_/src/protobuf-net.Core/ProtoReader.Stream.cs:395 
  at ProtoBuf.ProtoReader+StreamProtoReader.ImplReadUInt32Fixed (ProtoBuf.ProtoReader+State& state) [0x00009] in /_/src/protobuf-net.Core/ProtoReader.Stream.cs:353 
  at (wrapper dynamic-method) LocationUpdate+UserLocation.proto_12(ProtoBuf.ProtoReader/State&,LocationUpdate/UserLocation)
  at ProtoBuf.Internal.Serializers.SimpleCompiledSerializer`1[T].ProtoBuf.Serializers.ISerializer<T>.Read (ProtoBuf.ProtoReader+State& state, T value) [0x00000] in /_/src/protobuf-net/Internal/Serializers/CompiledSerializer.cs:107 
  at ProtoBuf.ProtoReader+State.ReadMessage[TSerializer,T] (ProtoBuf.Serializers.SerializerFeatures features, T value, TSerializer& serializer) [0x00007] in /_/src/protobuf-net.Core/ProtoReader.State.ReadMethods.cs:1022 
  at ProtoBuf.ProtoReader+State.FillBuffer[TSerializer,T] (ProtoBuf.Serializers.SerializerFeatures features, TSerializer& serializer, T initialValue) [0x0005f] in /_/src/protobuf-net.Core/ProtoReader.State.ReadMethods.cs:307 
  at ProtoBuf.Serializers.RepeatedSerializer`2[TCollection,TItem].ReadRepeated (ProtoBuf.ProtoReader+State& state, ProtoBuf.Serializers.SerializerFeatures features, TCollection values, ProtoBuf.Serializers.ISerializer`1[T] serializer) [0x00079] in /_/src/protobuf-net.Core/Serializers/RepeatedSerializer.cs:346 
  at (wrapper dynamic-method) LocationUpdate.proto_10(ProtoBuf.ProtoReader/State&,LocationUpdate)
  at ProtoBuf.Internal.Serializers.SimpleCompiledSerializer`1[T].ProtoBuf.Serializers.ISerializer<T>.Read (ProtoBuf.ProtoReader+State& state, T value) [0x00000] in /_/src/protobuf-net/Internal/Serializers/CompiledSerializer.cs:107 
  at ProtoBuf.ProtoReader+State.ReadAsRoot[T] (T value, ProtoBuf.Serializers.ISerializer`1[T] serializer) [0x00031] in /_/src/protobuf-net.Core/ProtoReader.State.ReadMethods.cs:1157 
  at ProtoBuf.ProtoReader+State.DeserializeRoot[T] (T value, ProtoBuf.Serializers.ISerializer`1[T] serializer) [0x00000] in /_/src/protobuf-net.Core/ProtoReader.State.ReadMethods.cs:1137 
  at ProtoBuf.Serializer.Deserialize[T] (System.IO.Stream source) [0x0000f] in /_/src/protobuf-net/Serializer.Deserialize.cs:21 
  at Packets.Deserialize[T] (System.Byte[] data) [0x00007] in C:\Users\youmi\Desktop\node5_unity_sample-challenge2\Assets\Src\Codes\Packets.cs:29 
UnityEngine.Debug:LogError (object)
Packets:Deserialize<LocationUpdate> (byte[]) (at Assets/Src/Codes/Packets.cs:34)
NetworkManager:HandleLocationPacket (byte[]) (at Assets/Src/Codes/NetworkManager.cs:289)
NetworkManager:ProcessReceivedData (byte[],int) (at Assets/Src/Codes/NetworkManager.cs:242)
NetworkManager/<ReceivePacketsAsync>d__24:MoveNext () (at Assets/Src/Codes/NetworkManager.cs:202)
UnityEngine.UnitySynchronizationContext:ExecuteTasks ()

맨위에 있는 오류다 굉장히 긴데 이 오류는 Protobuf를 이용해 데이터를 역직렬화(deserialization)할 때, 스트림 끝을 초과하여 데이터를 읽으려 할 때 발생하는 문제를 나타낸다.

 

서버가 보낸 버퍼가 잘못 되었거나  클라이언트가 제대로 버퍼를 읽지 못하거나 상호간 프로토형식이 일치하지 않는다거나 라고 생각하는데 GPT에 물어보니 다음과 같다.

주요 원인

  1. 전송된 데이터가 불완전함:
    • 네트워크 전송 중 데이터가 손실되었거나 중단되어, ProtoBuf에서 역직렬화할 수 있는 완전한 데이터가 제공되지 않았을 가능성이 있습니다.
    • 예를 들어, 패킷 크기를 잘못 계산하거나 데이터가 분리되어 처리되었을 수 있습니다.
  2. 역직렬화 대상 데이터 구조 불일치:
    • 서버 또는 클라이언트에서 사용하는 데이터 구조 정의(.proto 파일)가 서로 다를 수 있습니다.
    • 필드 추가, 삭제, 또는 타입 변경 시 이러한 오류가 발생할 수 있습니다.
  3. 패킷 크기 정보가 잘못 전달됨:
    • 일반적으로 네트워크 프로토콜은 패킷 크기를 데이터 헤더에 포함합니다. 만약 크기 정보가 잘못되면, 스트림의 끝을 초과하여 읽으려 하게 됩니다.
  4. 올바르지 않은 데이터로 역직렬화 시도:
    • 역직렬화 대상 데이터가 올바르지 않은 바이트 배열일 수 있습니다. 예를 들어, 다른 데이터 타입의 패킷을 잘못 전달했거나 데이터를 읽는 순서가 잘못된 경우입니다.

지금까지 진행했던걸 떠올려보면 1,4는 아니었다.

 

2번 아니면 3번 문제인데 그래서 일단 프로토파일을 다 체크해봤는데 일치했다.

 

그럼 3번이었고 유니티에서 보여준 에러중 2번째를 보면 HandleLocationPacket이 잘못된걸 볼 수 있다.

그래서 그 패킷을 보내는 곳을 찾아봤다. 그리고 패킷을 만들어 내는곳을 봤는데,

// 패킷 생성 함수
const makeNotification = (message, type) => {
  // 패킷 길이 정보를 포함한 버퍼 생성
  const packetLength = Buffer.alloc(4);
  packetLength.writeUInt32BE(message.length + 1, 0); // 패킷 길이에 타입 바이트 포함

  // 패킷 타입 정보를 포함한 버퍼 생성
  const packetType = Buffer.alloc(1);
  packetType.writeUInt8(type, 0);

  // 길이 정보와 메시지를 함께 전송
  return Buffer.concat([packetLength, packetType, message]);
};

 

이렇게 돼있었다. 지금 packetLength를 보면 메세지의 길이만을 더하고 있는데 우리가 보낼 패킷은 헤더도 들어간다.

내가 패킷길이에 헤더크기를 포함하지 않아서 클라이언트에서 요상한 패킷이라 본것이었다.

 

const makeNotification = (message, type) => {
  // 패킷 길이 정보를 포함한 버퍼 생성
  const packetLength = Buffer.alloc(4);
  packetLength.writeUInt32BE(TOTAL_LENGTH + message.length + 1, 0); // 패킷 길이에 타입 바이트 포함

  // 패킷 타입 정보를 포함한 버퍼 생성
  const packetType = Buffer.alloc(1);
  packetType.writeUInt8(type, 0);

  // 길이 정보와 메시지를 함께 전송
  return Buffer.concat([packetLength, packetType, message]);
};

그래서 packetLength에 헤더의 총 크기를 env에 정의해둔 TOTAL_LENGTH를 더해주었다.

 

그랬더니 해결!

'트러블슈팅' 카테고리의 다른 글

중복 랜더링  (0) 2025.01.17
웹소캣게임 트러블슈팅  (0) 2024.12.18