네트워크 버퍼 메커니즘

Jaemyeong Lee·2025년 1월 10일

게임 서버1

목록 보기
125/220

커널 버퍼가 필요한 이유

큰 그림

App(send/recv) <-> 커널 송수신 버퍼 <-> NIC/네트워크 <-> 상대 커널 버퍼 <-> 상대 App
  • 애플리케이션 속도와 네트워크 속도는 항상 다릅니다.
  • 커널 버퍼는 이 속도 차이를 흡수하는 완충 장치 역할을 합니다.
  • 그래서 send/recv는 "즉시 전송/즉시 수신"이 아니라 "버퍼와 상호작용"입니다.

소켓별 버퍼

항목설명
송신 버퍼앱이 보낸 데이터를 임시 저장 후 OS가 전송
수신 버퍼네트워크에서 받은 데이터를 앱이 recv하기 전 저장
위치커널 영역(앱 버퍼와 별개)

핵심 결론

  • 네트워크 API를 잘 쓰려면 "함수 호출"보다 "버퍼 상태"를 먼저 생각해야 합니다.

send() 경로와 반환값 해석

동작 흐름

  1. 앱 버퍼 -> 커널 송신 버퍼 복사 시도
  2. 복사된 바이트 수를 반환
  3. 실제 선로 전송은 OS가 백그라운드 수행

반환값 의미

반환의미
> 0이번 호출에서 큐잉/복사된 바이트 수
SOCKET_ERROR실패 (WSAGetLastError 확인)

블로킹 vs 논블로킹

  • 블로킹 소켓: 버퍼 여유가 생길 때까지 대기할 수 있음
  • 논블로킹 소켓: 즉시 실패(WSAEWOULDBLOCK)할 수 있음
int n = send(s, data, len, 0);
if (n == SOCKET_ERROR) {
    int err = WSAGetLastError();
    if (err == WSAEWOULDBLOCK) {
        // 나중에 재시도할 pending 송신 큐에 적재
    } else {
        // 실제 오류 처리
    }
}

recv() 경로와 반환값 해석

동작 흐름

  1. 커널 수신 버퍼에 데이터가 있는지 확인
  2. 있으면 요청한 최대 길이만큼 앱 버퍼로 복사
  3. 없으면 블로킹 대기 또는 WSAEWOULDBLOCK

반환값 요약

반환의미
> 0복사된 바이트 수
0상대가 정상 종료(FIN)
SOCKET_ERROR오류 발생

중요한 성질

  • TCP는 스트림이므로 경계가 없습니다.
  • 한 번의 recv가 "내가 기대한 메시지 1개"를 정확히 주는 보장은 없습니다.
  • 따라서 상위 프로토콜(길이 헤더/패킷 파서)이 필수입니다.

흐름 제어(Flow Control)와 백프레셔

왜 send가 막히는가

  • 상대가 recv를 늦게 하면 상대 수신 버퍼가 차고,
  • TCP 윈도우 광고가 줄어들어 송신 측 전송량이 제한됩니다.
  • 결과적으로 송신 측 send도 지연/실패(WOULDBLOCK)가 증가합니다.

실무에서 보이는 현상

현상관찰 포인트
송신 큐 길이 증가앱 내부 pending send queue가 계속 쌓임
지연 증가RTT/응답시간 상승
메모리 증가큐잉된 패킷 누적
disconnect 증가타임아웃/정책에 의한 연결 정리

대응 원칙

  • 무제한 큐잉 금지(최대 pending 바이트 설정)
  • 임계치 초과 시 drop 또는 연결 종료 정책
  • 송신 우선순위/압축/배치 전략 적용

버퍼 크기와 튜닝 관점

기본 인식

  • "기본 버퍼 크기 = 정답"이 아닙니다.
  • 트래픽 패턴(짧은 패킷 다량 vs 큰 데이터 전송)에 따라 최적값이 달라집니다.

옵션 예시

옵션의미주의점
SO_SNDBUF송신 버퍼 크기 힌트크게 하면 메모리 사용 증가
SO_RCVBUF수신 버퍼 크기 힌트크게 하면 지연/메모리 trade-off

튜닝 방법

  • 감으로 조정하지 말고 지표(지연, 드롭, 큐 길이) 기반으로 변경
  • 변경 후 부하 테스트로 회귀 검증

운영 관측 지표(필수)

최소 수집 항목

  • 초당 send/recv 바이트
  • WSAEWOULDBLOCK 발생 횟수
  • pending send queue 길이(세션별/전체)
  • recv==0 종료 비율, 소켓 오류 코드 분포

장애 시 빠른 판단

  1. 특정 구간에서만 큐가 쌓이는가?
  2. 전체 세션에서 동시에 지연이 증가하는가?
  3. 네트워크 문제인지 애플리케이션 소비 속도 문제인지 분리 가능한가?

강의 시 유의사항

강조 포인트

  • 버퍼 메커니즘은 "send/recv 함수 설명"이 아니라 시스템 동작 모델입니다.
  • send 성공 의미와 recv 반환값 0 의미를 반드시 구분해 설명하세요.
  • 흐름 제어(backpressure)를 이해해야 이후 non-blocking/IOCP 설계가 자연스럽습니다.

자주 하는 오해

오해바로잡기
send 성공이면 상대가 이미 처리했다커널 송신 버퍼 등록 성공에 가깝다
recv는 한 번에 메시지 단위로 온다TCP는 스트림이므로 경계 없음
버퍼를 크게 하면 무조건 좋다메모리/지연/운영 정책 trade-off 존재

체크 질문 (스스로 답해보기)

  • WSAEWOULDBLOCK이 자주 발생할 때 무엇을 먼저 점검해야 하는가?
  • 왜 앱 레벨에서 길이 기반 패킷 파싱이 필요한가?
  • pending 송신 큐에 상한을 두지 않으면 어떤 장애가 생길 수 있는가?

profile
李家네_공부방

0개의 댓글