31. 프레임 무결성 검증(체크섬/CRC) 부재

난이도 상 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// [시나리오] 길이 프리픽스 프레임 수신 (서버-클라)
// 프레임 포맷: [4바이트 길이(len, payload 바이트 수)][2바이트 msgType][len-2 바이트 payload]
// 이 서버는 TCP 스트림에서 프레임을 잘라 msgType 에 따라 페이로드를 해석한다.
// 전송 구간에는 방화벽/프록시, 불안정한 무선 구간, 또는 악의적 중간자가 있을 수 있어
// 프레임 바이트가 전송 중 손상되거나 조작될 가능성이 있다.
//
// [요구사항]
//   - 손상되거나 조작된 프레임은 유효한 것으로 처리되어서는 안 된다.
//   - 한 프레임이 손상되어 거부되더라도, 이후 수신 스트림의 프레임 동기화(경계 인식)는
//     유지되어야 한다(다음 정상 프레임을 정상적으로 계속 처리할 수 있어야 한다).
//
// [과제] FrameReader.TryReadFrame 을 검토하고, 전송 중 프레임 일부가 손상/조작되었을 때
//        위 요구사항이 어떻게 어긋날 수 있는지 원인과 수정안을 제시하라.
//        표시된 (A)(B) 지점에 주목하라.

using System;

class FrameReader
{
    private byte[] _buf = new byte[64 * 1024];
    private int _len;   // _buf 안에 쌓인 유효 바이트 수

    public void OnBytesReceived(byte[] data, int count)
    {
        Array.Copy(data, 0, _buf, _len, count);
        _len += count;
    }

    // 완전한 프레임이 있으면 payload 를 반환하고 true, 아니면 false.
    public bool TryReadFrame(out ushort msgType, out ArraySegment<byte> payload)
    {
        msgType = 0;
        payload = default;

        if (_len < 6)
            return false;

        int frameLen = BitConverter.ToInt32(_buf, 0);   // (A)

        if (_len < 4 + frameLen)
            return false;   // 아직 다 안 옴

        msgType = BitConverter.ToUInt16(_buf, 4);
        payload = new ArraySegment<byte>(_buf, 6, frameLen - 2);

        // (B)
        int consumed = 4 + frameLen;
        Array.Copy(_buf, consumed, _buf, 0, _len - consumed);
        _len -= consumed;

        return true;
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.