TCP로 메시지를 두 번 보내면 받는 쪽에서도 두 번에 나눠 읽게 되나요?
잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?
답변과 점검 포인트 펼치기답변 접기
구두 답변
정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.
아닙니다. TCP는 순서가 있는 바이트 스트림을 전달할 뿐 송신자의 send 호출이나 애플리케이션 메시지 경계를 보존하지 않습니다. 두 번 보낸 100바이트가 수신자에게 200바이트 한 번으로 읽힐 수도 있고, 60바이트와 140바이트로 나뉠 수도 있습니다. 따라서 길이·구분자·고정 크기 같은 프레이밍을 애플리케이션 프로토콜이 정의하고, 수신 파서는 임의의 분할을 정상 입력으로 처리해야 합니다.
송신 횟수와 수신 횟수는 독립이다
TCP의 신뢰성은 연결이 정상적으로 유지되는 범위에서 바이트의 손실·중복·재정렬을 다루는 성질이지, 모든 연결 실패에도 모든 바이트가 애플리케이션에 전달된다는 보장이 아닙니다. 연결이 중간에 끊기면 송신자는 일부 바이트가 상대 TCP에 도착했는지, 상대 애플리케이션이 처리했는지 알 수 없습니다. 커널 버퍼, MSS, 네트워크 지연, 수신 버퍼 크기에 따라 여러 송신이 합쳐지거나 하나가 나뉘며 TCP_NODELAY도 경계를 만들지 않습니다. 이를 바이트 스트림과 메시지 프레이밍의 분리(stream/message separation)라고 부르겠습니다.
길이 헤더 방식이라면 먼저 고정 크기 헤더가 모두 모였는지 확인하고, 헤더에서 본문 길이를 읽은 뒤 최대값을 검사하고 그만큼 누적될 때만 프레임을 추출합니다. 한 번에 여러 프레임이 들어오면 소비 위치를 전진시키며 반복하고, 마지막 불완전 조각은 다음 read를 위해 보관합니다. 구분자 방식은 delimiter와 바이너리 데이터의 escape 규칙을 정의해야 합니다. 헤더·본문 중간 EOF는 정상 프레임 완료가 아니라 프로토콜 오류로 분류합니다.
길이·버퍼·재시도 경계
길이 필드를 그대로 믿으면 무제한 메모리 할당과 느린 입력을 허용할 수 있으므로, 최대 프레임 크기·정수 오버플로 검사·연결별 버퍼 상한·프레임 완성 deadline을 둡니다. 송신에서도 부분 전송이면 남은 오프셋을 기록하고 이어서 보냅니다. 여러 생산자가 같은 소켓에 프레임을 나눠 쓰면 조각이 섞일 수 있어 연결별 송신 큐에서 제출 순서를 관리하겠습니다.
send 성공이나 TCP ACK는 상대 애플리케이션의 DB 처리를 보장하지 않습니다. 응답 전에 연결이 끊긴 중요한 요청은 서버가 처리했는지 조회할 수 있는 요청 ID와 멱등 규칙을 사용해 재시도 여부를 정합니다. 테스트에서는 동일한 바이트 스트림을 모든 경계에서 잘라 넣어 같은 프레임 목록이 나오는지, 다중 프레임·EOF·비정상 길이·느린 입력을 검증합니다.
추가 조건과 판단
예를 들어 4바이트 길이 헤더 뒤 본문이 이어지는 프로토콜에서 처음 2바이트만 도착하면 아직 길이도 읽지 않습니다. 다음 읽기에서 나머지 헤더 2바이트와 본문 일부가 도착하면 길이를 검증하고 본문이 더 필요한 상태로 남습니다. 마지막 조각에 다음 프레임의 헤더까지 붙어 있다면 첫 프레임만 소비한 뒤 남은 위치부터 다시 반복합니다. 이를 증분 파싱(incremental parsing)이라고 부릅니다. 입력을 받는 횟수와 파서가 완성하는 메시지 수는 독립적입니다.
프레임을 별도 워커에 넘길 때는 수신 버퍼를 언제 재사용할지도 정해야 합니다. 버퍼의 뷰만 넘긴 뒤 다음 수신으로 덮어쓰면 파서가 정확해도 내용이 바뀝니다. 필요한 범위를 복사하거나 참조 수명과 소유권을 넘겨 소비가 끝난 뒤 반환해야 합니다. 링 버퍼를 쓴다면 프레임이 버퍼 끝과 시작에 걸치는 경우도 시험하고, 임의 조각 분할 테스트에 여러 프레임과 0길이·최대 길이·초과 길이를 포함하겠습니다. 한 조각을 중복 처리하거나 건너뛰지 않는 소비 위치가 핵심 불변식입니다.
득점 포인트
이해가 드러나는 지점을 확인해 보세요.
- TCP의 바이트 순서 보장과 메시지 경계 부재를 명확히 구분한다.
- 헤더·본문 누적, 다중 프레임 추출, 불완전 조각 보관 절차를 말한다.
- 길이 검증·버퍼 상한·완성 deadline으로 비정상 입력과 느린 연결을 제한한다.
- 송신 부분 전송과 TCP ACK·애플리케이션 처리 완료의 차이를 짚는다.
감점 포인트
놓치기 쉬운 조건과 오해를 짚어 보세요.
- TCP가 신뢰성이 있으므로 송신 메시지가 같은 단위로 수신된다고 말한다.
- 한 번의 recv나 큰 버퍼만으로 항상 한 프레임을 얻는다고 가정한다.
- 길이 필드와 버퍼를 무제한 믿어 메모리 고갈·slowloris를 허용한다.
- TCP ACK를 주문 저장이나 애플리케이션 처리 완료로 해석한다.
더 파고들 거리
하나 더 질문하며 이해의 범위를 넓혀 보세요.
- 수신 ring buffer의 일부를 복사 없이 파싱 결과로 넘깁니다. wrap·확장·재사용에서 참조 수명을 어떻게 보호하나요?
- 구분자 방식과 길이 헤더 방식이 손상된 입력 복구·바이너리 처리에서 어떻게 다를까요?
- 느린 수신자에게 보낼 프레임의 중요도별 폐기·백프레셔 정책을 어떻게 정할까요?
득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.
원리부터 공부하고 싶다면
답변을 보충하는 개념·예제·슈도코드를 읽어 보세요.