• 카테고리

    질문 & 답변
  • 세부 분야

    게임 프로그래밍

  • 해결 여부

    미해결

Name이 한번 오면 초기화되는 이유

23.03.11 16:24 작성 조회수 364

2

안녕하세요, string serialize를 하여 read, write 코드를 추가한 이후 확인해보려 코드를 실행해보았는데,

처음엔 name이 잘 나오지만 client에서 5번 연속으로 보냈을 때 name이 null인건지 나오질 않아 확인해보니, 아래와같이 처음 이후에는 name이 null이 되는 것 같습니다. 해당 이유를 찾기가 힘들어서 왜이러는지 이해가 되질 않습니다.

답변 4

·

답변을 작성해보세요.

0

jiw720님의 프로필

jiw720

질문자

2023.03.11

답변 감사합니다. 사실 바로 질문드리는건 아니고 보통 몇시간동안 삽질하다가 질문드리는것이었는데 부족했었던 것 같습니다. 더 열심히하겠습니다!!

그리고 해당 원인을 찾은것같습니다. read에서는 offset을 ReadOnlySpan<byte> s = new ReadOnlySpan<byte>(segment.Array,segment.Offset,segment.Count);

 

이렇게 offset을 반영하여 segment로 끌어왔는데 정작 write에서는 ArrayCopy할 때에 Offset을 더해주지않고 count만 넘겨주어 계속 첫 22바이트영역의 name부분에만 넣고 있었던겁니다.

 

(강의에서도 offset을 더하지 않은채로 진행했지만, 강사님께서는 5번 보내지않고 한번만 보내어 잘 동작된것처럼 보였던 것 같습니다.)

제일 이해안되었던게 다른건 다 잘나오는데 name만 이상하게 나오는 이유였는데, 해당 name을 copy해주는 array.copy에서 저렇게 해주어 첫 ABCD만 나오고 그 이후엔 애초에 name byte가 들어있지않으니 나오지 않았던것입니다.

 

실제로 이런 실수 문제를 줄이기 위해서는 다른 리팩토링 과정이 필요할 것 같은데 어떻게할지는 전혀 지식이 없어서 필요하겠구나..만 생각이 드네요.

 

저는 다른 일을하고있어서 해당 강의를 병행할 시간이 별로 없어서그런지 빨리 해당 기술을 배워 일에 적용시켜야하는 급한 마음에 몇시간동안 계속 삽질해보다 질문을 드렸었는데, 강사님의

"어차피 현업에 가더라도 지금과 마찬가지로 알 수 없는 문제들이 막 터지는데
그 때는 누군가 옆에서 도와주고 답을 알려주는 사람이 있지 않습니다."

가 굉장히 마음에 와 닿았습니다. 마음에 새기며 더 열심히 해보겠습니다. 좋은강의, 답변 감사드립니다!

 

알겠습니다.
간혹 라이브러리가 '왜' 그런 것인지 이유를 묻는 질문을 자주 하셔서
그냥 별 생각 없이 질문을 하신다 생각했는데 살짝 오해한 모양이네요.
정말 고민 후에 질문하신다고 가정하고, 답변을 드리도록 하겠습니다.

jiw720님의 프로필

jiw720

질문자

2023.03.12

앗 그러셨군요 저도 감사합니다. 강사님 말씀대로 더 생각해보는 시간이 많을수록 뭔가 알아냈을 때, 확실히 저한테 더 와닿고, 연쇄적으로 이해가 팍 가는 느낌이 들어 좋습니다 ㅎㅎ 감사합니다~!

0

찾지 못했으면 질문을 하는 것이 수순이 아니고,
찾을 때까지 삽질을 하는 것이 중요합니다.
어차피 현업에 가더라도 지금과 마찬가지로 알 수 없는 문제들이 막 터지는데
그 때는 누군가 옆에서 도와주고 답을 알려주는 사람이 있지 않습니다.

여러 프로그래밍 디버깅 하는 정석적인 방법은 없습니다.
정말 VS을 여러개 켜는 방법도 있을 수 있고 (솔루션을 분리해서)
한쪽을 멈추면 다른 쪽은 이미 비정상 진행되는 상황이므로
한쪽만 보면서 반대쪽을 예상하면서 가는 수 밖에 없습니다.

0

jiw720님의 프로필

jiw720

질문자

2023.03.11

저도 디버깅을 하고싶지만, 디버깅을 하면 client또는 server둘중 하나만 디버깅이 가능해서 값을 주고받는것에 대한 테스트가 안됩니다. 그래서 강사님은 어떻게 두 프로그램을 동시에 디버깅하시는지에 대해 질문을 올린적이 있습니다..ㅜ
그래서 현재 자세하게 디버깅을 할 수가없어 console writeline으로 확인해보며 값을 체크를 하였지만 찾지 못하여 질문드렸습니다. write()메서드를 이후의 방법으로 바꿔보았을 때 잘 되는것으로 보아, write()의 string serializable부분코드가 잘못된 것 같아보여서 해당 코드 첨부드립니다..

 

 

 

 

 public override ArraySegment<byte> Write()
        {
            //이만큼의 버퍼를 일단 가져옴
            ArraySegment<byte> segment = SendBufferHelper.Open(4096);

            ushort count = 0;
            bool success = true;


            //처음에만 span으로 찝어주고 이후에 slice
            Span<byte> s = new Span<byte>(segment.Array, segment.Offset, segment.Count);

       

            count += sizeof(ushort);

            
            success &= BitConverter.TryWriteBytes(s.Slice(count,s.Length-count), this.packetId);
            count += sizeof(ushort);
            success &= BitConverter.TryWriteBytes(s.Slice(count,s.Length-count), this.playerId);
            count += sizeof(long);



            //string serialize

            
            ushort nameLen = (ushort)Encoding.Unicode.GetByteCount(this.name);
            success &= BitConverter.TryWriteBytes(s.Slice(count, s.Length - count), nameLen);
            count += sizeof(ushort);

             // TryWriteBytes()에서 string, byte[]을 인자로 받는 메서드가 없어서 이렇게 구현
            Array.Copy(Encoding.Unicode.GetBytes(this.name), 0, segment.Array, count, nameLen);
            count += nameLen;


           

            success &= BitConverter.TryWriteBytes(s, count);

            if (success == false)
            {
                return null;
            }
            //실제로 사용한 데이터 범위 가져옴
            return  SendBufferHelper.Close(count);
            
        }

 

 

0

위 스샷만 보고는 저도 알 수가 없습니다.
1일 이상 고민하고 디버깅하고 삽질을 해봐야 문제 해결 능력이 향상됩니다.
그 정도로 고민해도 해결이 안 되는 부분만 질문 주세요.