inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버

Serialization #3

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

515

태사단

작성한 질문수 17

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# network unity

답변 5

2

Rookiss


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

0

태사단

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

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

0

태사단

넵 방금 메일 보냈습니다!

0

Rookiss

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

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

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

TLS 질문드립니다.

0

39

2

SpinLock과 컨텍스트스위칭에 대해 질문 남겨요.

0

45

2

Unity Span

0

73

2

XML, Dll 차이점

0

103

2

Session 질문입니다

0

78

1

Write Read 커서 키워드

0

72

1

더미 클라이언트 수에 따른 OnDisconnect 발생

0

68

2

네트워크 Send 전담 스레드 배치

0

97

2

UnhandledException 으로 서버 터지는 경우

0

84

2

컨텐츠 단, 엔진 단

0

103

1

질문 있습니다

0

76

2

C# 게임서버 3D MMORPG

0

143

2

유니티6 버전

0

96

2

receive하는 부분과 send하는 부분의 차이

0

132

2

커서의 위치의 중요성

0

102

2

C++ 전혀 모르는데 C# 서버

0

169

2

강의에 질문이 있습니다

0

85

2

멀티스레드 이해도 질문

0

94

1

500 vs 500

0

127

3

OnAcceptHandler 액션 함수

0

60

1

이 정도 서버의 객관적인 수준이 궁금합니다.

0

187

2

36. Serialization #3 에서 string (name) 코드 수정 질문

0

81

2

외부 컴퓨터와의 통신 방법이 궁금합니다

0

104

1

스핀락 질문.

0

109

2