38. 세션 간 공유 직렬화 버퍼 오염: 데이터 유출·프레임 붕괴 (C#)

난이도 상 해설 보기 →

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

결함 코드 · C#
// 시나리오: MMORPG 게이트웨이. 각 클라이언트 세션으로 메시지를 보낼 때, 매번 배열을
// 새로 할당하지 않으려고 직렬화용 스크래치 버퍼를 재사용한다. 직렬화한 뒤 그 버퍼를
// 소켓으로 비동기 전송한다. 여러 세션이 서로 다른 스레드에서 동시에 전송한다.
//
// 요구사항:
//  - 각 세션은 자기 메시지 바이트만 자기 소켓으로 보내야 한다.
//  - 한 세션의 데이터가 다른 세션의 프레임에 섞이거나 다른 소켓으로 나가면 안 된다.
//  - 직렬화 결과는 전송이 끝날 때까지 온전히 유지되어야 한다.
//
// 과제: SendAsync 를 검토하고, 동시에 여러 세션이 전송할 때 무엇이 잘못될 수 있는지,
//       어떤 조건에서 드러나는지, 어떻게 고칠지 설명하라. (A)(B) 지점을 살펴보라.

using System.Net.Sockets;
using System.Threading.Tasks;

public interface IMessage { int Serialize(byte[] dest); }

public sealed class MessageSender
{
    // 할당을 줄이려고 직렬화 스크래치 버퍼를 재사용한다.
    private static readonly byte[] _scratch = new byte[4096];   // (A)

    public async Task SendAsync(Socket socket, IMessage msg)
    {
        int len = msg.Serialize(_scratch);                       // 스크래치에 직렬화
        await socket.SendAsync(
            new ArraySegment<byte>(_scratch, 0, len), SocketFlags.None);   // (B)
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

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