작성
·
386
0
class PlayerInfoReq : Packet
{
public long playerId;
public string playerName;
public string nickName;
public PlayerInfoReq()
{
packetId = (ushort)PacketID.PlayerInfoReq;
}
public override ArraySegment<byte> Write()
{
ArraySegment<byte> segment = SendBufferHelper.Open(4096);
ushort count = 0;
bool success = true;
Span<byte> span = new Span<byte>(segment.Array, segment.Offset, segment.Count);
count += sizeof(ushort);
success &= BitConverter.TryWriteBytes(span.Slice(count, span.Length - count), packetId);
count += sizeof(ushort);
success &= BitConverter.TryWriteBytes(span.Slice(count, span.Length - count), playerId);
count += sizeof(long);
ushort nameLen = (ushort)Encoding.Unicode.GetByteCount(playerName);
success &= BitConverter.TryWriteBytes(span.Slice(count, span.Length - count), nameLen);
count += sizeof(ushort);
Array.Copy(Encoding.Unicode.GetBytes(playerName), 0, segment.Array, count, nameLen);
count += nameLen;
nameLen = (ushort)Encoding.Unicode.GetBytes(nickName, 0, nickName.Length, segment.Array, segment.Offset + count + sizeof(ushort));
success &= BitConverter.TryWriteBytes(span.Slice(count, span.Length - count), nameLen);
count += sizeof(ushort);
count += nameLen;
success &= BitConverter.TryWriteBytes(span, count);
if (!success)
return null;
return SendBufferHelper.Close(count);
}
public override void Read(ArraySegment<byte> segment)
{
ushort count = 0;
count += sizeof(ushort);
count += sizeof(ushort);
ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(segment.Array, segment.Offset, segment.Count);
playerId = BitConverter.ToInt64(span.Slice(count, span.Length - count));
count += sizeof(long);
ushort nameLen = BitConverter.ToUInt16(span.Slice(count, span.Length - count));
count += sizeof(ushort);
playerName = Encoding.Unicode.GetString(span.Slice(count, nameLen));
count += nameLen;
nameLen = BitConverter.ToUInt16(span.Slice(count, span.Length - count));
count += sizeof(ushort);
nickName = Encoding.Unicode.GetString(span.Slice(count, nameLen));
count += nameLen;
}
}
답변 5
2
이런 문제를 찾는 요령은
우선 클라 문제인지 서버 문제인지를 먼저 파악하는겁니다.
서버에서 받는 데이터 내용을 보니 1번째 데이터와 2번째 데이터가 상이한 것을 알 수 있고,
그렇다면 클라에서 전송하는 부분의 문제라는 것을 짐작할 수 있습니다.
데이터를 만들어주는 부분을 유심히 살펴보면
오프셋 계산이 잘못된 것을 확인할 수 있습니다.
0
앗... 첫 번째 string에 오프셋을 빠뜨렸네요. 그래서 playerName은 같은 곳에 계속 저장되니까 첫 번째 출력만 나왔고...
Read() 부분 문제인 줄 알고 한참 헤맸습니다 ㅠㅠ 감사합니다!
0
0
0
엇... 코드 빼고 본문 내용이 다 잘렸네요 ㅠ 간단하게 다시 적겠습니다
Serialization #3 강의에서 string을 직렬화하는 두 가지 방식이 나옵니다.
인코딩한 string을 Array.Copy로 복사하는 방법과, Encoding.Unicode.GetBytes에 오버로딩된 함수를 이용하여 인코딩 결과를 지정한 메모리 주소에 직접 입력하는 방식입니다.
두 방법을 다 실습해보고 싶어서 패킷 클래스에 playerName, nickName 두 가지 문자열 변수를 선언했습니다. 패킷을 보낼 때 값은 "이름", "닉네임" 으로 초기화했어요. 서버에서 Read()를 통해 읽은 후
Console.WriteLine($"Player Info Required : {packet.playerId} / {packet.nickName} ({packet.playerName})");
을 통해서 실행했더니,
위와 같이 두 번째 출력부터 playerName 문자열의 문자가 모두 NULL 문자(\0) 으로 나옵니다.
break point를 찍어보니 개수는 동일한데 \0\0\0... 이런 식으로 공백 문자로만 나오는데, 0으로 가득 찬 비트 배열을 읽고 있는 것 같습니다. 따로 예외 처리는 되지 않고요.
혹시 원인을 알려주실 수 있으신가요? 아무리 고민해봐도 모르겠어서 여쭤봅니다 ㅠㅠ 첫번째엔 왜 출력되는지도 모르겠습니다...