엔디언과 htons

Jaemyeong Lee·2025년 1월 10일

게임 서버1

목록 보기
126/220

엔디언(Endian) 핵심 개념

정의

방식0x12345678 저장 순서
리틀 엔디언78 56 34 12 (하위 바이트 먼저)
빅 엔디언12 34 56 78 (상위 바이트 먼저)

왜 네트워크에서 중요한가

  • 대부분의 PC CPU(x86/x64)는 리틀 엔디언입니다.
  • 네트워크 표준(Network Byte Order)은 빅 엔디언입니다.
  • 따라서 멀티바이트 정수(포트, 길이, ID 등)는 송수신 시 바이트 순서를 맞춰야 합니다.

핵심 정리

  • "내 컴퓨터에서 정상"이어도, 다른 환경과 통신하면 순서 mismatch가 드러납니다.
  • 엔디언 변환은 선택이 아니라 프로토콜 일관성 규약입니다.

변환 함수 htons/htonl과 역변환

함수 매핑

함수의미대상 크기
htonsHost -> Network Short2바이트(uint16_t)
htonlHost -> Network Long4바이트(uint32_t)
ntohsNetwork -> Host Short2바이트
ntohlNetwork -> Host Long4바이트

사용 위치 규칙

  • 전송 전에: host -> network (htons, htonl)
  • 수신 후 해석 전에: network -> host (ntohs, ntohl)
  • "송신 측 한 번 + 수신 측 한 번" 쌍으로 기억하면 실수가 줄어듭니다.

실제 예시: 포트 7777을 왜 변환하나

코드

sockaddr_in addr{};
addr.sin_family = AF_INET;
addr.sin_port = htons(7777);  // 필수

변환 안 하면 생기는 문제

  • 7777(0x1E61)을 변환 없이 넣으면 리틀 엔디언 메모리상 61 1E
  • 네트워크는 이를 빅 엔디언으로 해석해 0x611E(24862)로 오인할 수 있습니다.
  • 결과: "분명 7777로 열었는데 접속이 안 됨" 같은 디버깅 난제가 발생합니다.

주소/포트에서의 주의점

  • sin_port는 항상 network order로 저장해야 합니다.
  • inet_pton으로 변환한 IPv4/IPv6 주소는 이미 network order 형식입니다.

수신 측 역변환 예시

접속 클라이언트 포트 출력

sockaddr_in clientAddr{};
int len = sizeof(clientAddr);
SOCKET clientSock = accept(listenSock, reinterpret_cast<sockaddr*>(&clientAddr), &len);
if (clientSock != INVALID_SOCKET) {
    uint16_t clientPort = ntohs(clientAddr.sin_port);  // 역변환
    // log: clientPort
}

패킷 헤더에서도 동일

  • 길이(uint16_t), 타입(uint16_t), 시퀀스(uint32_t) 같은 필드는
  • 직렬화/역직렬화 시 host/network 변환 규칙을 반드시 동일하게 적용해야 합니다.

입문 단계에서 자주 하는 실수

실수결과예방
sin_port = 7777 그대로 대입잘못된 포트 해석 가능htons(7777) 사용
송신만 변환하고 수신 역변환 누락헤더 값 파싱 오류ntoh*를 수신 루틴에 고정
inet_pton 결과에 추가 변환주소 값 왜곡inet_pton 출력은 그대로 사용
엔디언 규칙을 문서화 안 함팀별 구현 불일치프로토콜 문서에 바이트 오더 명시

강의 시 유의사항

강조 포인트

  • 엔디언은 암기 과목이 아니라 "서로 다른 시스템 간 약속"입니다.
  • 포트 오류 재현(7777 -> 24862 오해)을 보여주면 이해가 매우 빨라집니다.
  • Part 9 패킷 포맷 설계와 반드시 연결해서 설명하세요.

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

  • 왜 네트워크 바이트 오더는 빅 엔디언으로 정의되어 있는가?
  • htons를 빼먹었을 때 어떤 증상이 나타나는가?
  • inet_pton 결과를 다시 htonl하면 왜 문제가 될 수 있는가?

profile
李家네_공부방

0개의 댓글