작성
·
247
0
안녕하세요.
Serialization #2 강의 17:41초에 보면 Count는 4, count도 4해서 Count - count = 0 이라고 출력되는데
이해가 되지 않는 점은 Count는 12 아닌가요?
p.Read(buffer); 는 매개변수로 원본데이터 12바이트를 그대로 넘겨서 Count = 12, count=4가 되서
Count - count = 8이 된다고 생각하는데
어떤 점을 잘못이해하고 있는지 모르겠습니다.
p.Read(buffer); 에서 어떻게 4바이트 크기 버퍼만 넘어갔나요?
제가 헷갈려서 두서없이 질문드린 점 죄송합니다..
답변 4
2
buffer에 있는 12바이트 배열을 p.Read(buffer)로 넘기면 <<
이 부분을 잘못 이해하고 계십니다.
12바이트 배열을 넘기지 않고 그 중 4 바이트만큼을 쪼개서 넘기고 있습니다.
패킷을 조립하는 코드 PacketSession의 OnRecv를 유심히 디버깅 해보면
dataSize는 12가 아니라 4인 것을 볼 수 있는데요.
이는 네트워크 상에서 보내준 데이터 크기와 무관하며
클라에서 적어준 패킷 사이즈 정보입니다. (ushort)4로 강제로 클라에서 넣어준 부분 <<
이렇게 하는 이유는 TCP 패킷 특성상
패킷은 조각나서 부분적으로 올 수 있기 때문에,
서버 입장에서 [원본 크기]라는 것을 아예 알 수 없기 때문입니다.
그래서 클라가 보내준 [패킷 크기]를 믿고 일단 패킷을 조립하는 것입니다.
클라에서 패킷 조작을 했으면 이를 걸러내는 것도 서버의 임무 중 하나입니다.
// 패킷이 완전체로 도착했는지 확인
ushort dataSize = BitConverter.ToUInt16(buffer.Array, buffer.Offset);
이 부분은 배열의 크기를 구하는게 아니라, 배열의 첫 2바이트를 파싱해서
클라에서 적어준 dataSize를 추출하는 것입니다.
// 여기까지 왔으면 패킷 조립 가능
OnRecvPacket(new ArraySegment<byte>(buffer.Array, buffer.Offset, dataSize));
이 부분에서 전체 버퍼를 dataSize만큼 쪼개서 다음으로 넘겨주고 있기 때문에
다음으로 넘어가면 s.Count가 4 (dataSize)로 보이는거죠.
ArraySegment는 배열을 쪼개서 쓰기 위한 래퍼 클래스라고 보시면 됩니다.
0
0
강사님 저는 아래와 같이 이해했는데 뭔가 이상합니다ㅠ
클라에서
TryWriteBytes(new Span<byte>(s.Array, s.Offset, s.Count), (ushort )4)를 통해
2byte 부호 없는 4를 바이트 범위로 변환합니다.
서버에서 OnRecvPacket(ArraySegment<byte> buffer)를 통해
ushort size에 2Byte 크기로 저장된 숫자 4가 대입됩니다.
그리고 buffer에 있는 12바이트 배열을 p. Read(buffer)로 넘기면
ReadOnlySpan<byte>(s.Array, s.Offset + count, s.Count - count)로 넘어오는데
이때 Count가 어떻게 4바이트가 되나요??
MSDN에서
TryWriteBytes(Span<Byte>, ushort value) 16비트 부호 없는 정수를 바이트 범위로 변환하고 적혀있는데
(ushor)4가 어떻게 Count = 4로 넘어가는지 이해가 되지 않습니다.
0
원래 Count=12가 정상적인 값은 맞는데,
서버를 제작하는 입장에서 모든 값들이
항상 정상적이라고 가정할 수는 없습니다.
Count=12대신 Count=4가 된 이유는
13:25 보시면 강제로 ushort(4)로 조작해서
클라에서 잘못된 Count를 보내주고 있기 때문입니다.
한마디로 해커가 악의적으로 패킷 조작한 것을 시뮬레이션 하고,
그럼에도 서버에서 정상적으로 처리를 하는지(혹은 걸러내는지)를 보고 있다고 생각하시면 됩니다.