강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của seojiho10786
seojiho10786

câu hỏi đã được viết

[Series Phát triển Game MMORPG với C# và Unity] Part4: Game Server

Serialization #3

두번째 출력부터 이름이 제대로 나오지 않습니다

Viết

·

501

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;
		}
	}
C#networkunity

Câu trả lời 5

2

Rookiss님의 프로필 이미지
Rookiss
Người chia sẻ kiến thức


이런 문제를 찾는 요령은
우선 클라 문제인지 서버 문제인지를 먼저 파악하는겁니다.
서버에서 받는 데이터 내용을 보니 1번째 데이터와 2번째 데이터가 상이한 것을 알 수 있고,
그렇다면 클라에서 전송하는 부분의 문제라는 것을 짐작할 수 있습니다.
데이터를 만들어주는 부분을 유심히 살펴보면
오프셋 계산이 잘못된 것을 확인할 수 있습니다.

0

seojiho10786님의 프로필 이미지
seojiho10786
Người đặt câu hỏi

앗... 첫 번째 string에 오프셋을 빠뜨렸네요. 그래서 playerName은 같은 곳에 계속 저장되니까 첫 번째 출력만 나왔고...

Read() 부분 문제인 줄 알고 한참 헤맸습니다 ㅠㅠ 감사합니다!

0

seojiho10786님의 프로필 이미지
seojiho10786
Người đặt câu hỏi

넵 방금 메일 보냈습니다!

0

Rookiss님의 프로필 이미지
Rookiss
Người chia sẻ kiến thức

안녕하세요,
프로젝트를 통으로 압축해서 rookiss@naver.com으로 보내주시면 살펴보겠습니다.
딱 그 버전에 맞는 코드가 없네요 :(

0

seojiho10786님의 프로필 이미지
seojiho10786
Người đặt câu hỏi

엇... 코드 빼고 본문 내용이 다 잘렸네요 ㅠ 간단하게 다시 적겠습니다

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으로 가득 찬 비트 배열을 읽고 있는 것 같습니다. 따로 예외 처리는 되지 않고요.

혹시 원인을 알려주실 수 있으신가요? 아무리 고민해봐도 모르겠어서 여쭤봅니다 ㅠㅠ 첫번째엔 왜 출력되는지도 모르겠습니다... 

Hình ảnh hồ sơ của seojiho10786
seojiho10786

câu hỏi đã được viết

Đặt câu hỏi