해결된 질문
작성
·
207
0
안녕하십니까? 강의 정말 잘 들었습니다!
궁금한 점이 있어 질문 드립니다.
네트워크에서는 빅 엔디언이 표준으로 알고 있습니다. 그래서 제가 헤더에 값을 채우고 이를 송수신하면 당연히 빅 엔디언일 것이라고 생각하고 있었습니다. 그런데 개발을 하면서 보니 Windows에서 소켓을 통해 보내는 데이터가 htonl() 같은 함수를 쓰지 않고 구조체에 데이터를 넣으면, 리틀 엔디언으로 보내더라고요.
소켓 프로그래밍이 처음이다 보니 빅 엔디언과 리틀 엔디언에 대한 일반적인 룰이 존재하는지 궁금하여 질문을 드리고 싶습니다.
일반적으로 데이터를 송수신할 때, 모든 변수를 다 빅엔디언으로 변환하여 헤더나 페이로드에 넣고 전송한 후 수신한 빅엔디언을 전부 리틀 엔디언으로 변환하여 사용하나요? 아니면 송신할 때 리틀엔디언으로 보내고, 수신하는 쪽도 리틀엔디언으로 디코딩해서 쓰는 것도 일반적인지 궁금합니다.
감사합니다.
답변 2
1
네트워크가 Big endian 방식을 사용하는 이유는 Big endian 방식을 사용하는 쪽에서 네트워크를 만들고 표준을 정했기 때문입니다. 이런 이유로 IP패킷을 분석해보면 패킷의 길이(16bit)나 포트번호(16bit) 값 같은 것들은 모두 Big endian 입니다. 그러나 이런 규칙들이 응용 프로그램수준까지 적용되는 것은 아닙니다.
질문한 것처럼 Little endian 시스템을 사용하고 있다면 구조체 멤버나 일반 변수 모두 Little endian이 적용됩니다. 이를 네트워크로 전송하더라도 그 값이 Big endian으로 변환되지 않습니다.
그리고 이와 관련한 룰이 따로 있지는 않습니다. 네트워크 자체와 그에 관련한 라이브러리 들이 앞서 언급한 것처럼 Big endian 시스템을 사용하는 쪽에서 만든 것이라 소켓 라이브러리에서 포트번호 같은 정보를 기술할 때는 변환이 필요하겠습니다. 그러나 소켓으로 송/수신하는 데이터는 전혀 관련이 없습니다. 가령 통신하는 서버와 클라이언트 모두 Little endian을 사용한다면 굳이 Big endian으로 변환했다가 다시 Little endian으로 변환함으로써 효율을 떨어뜨릴 이유가 없습니다. 참고하시기 바랍니다. 😄
0
안녕하세요, 인프런 AI 인턴입니다.
philip.jung92님, 네트워크 프로그래밍에 관한 질문을 주셔서 감사합니다.
네트워크 통신에서 사실 빅 엔디언이 일반적으로 사용되는 표준이 맞습니다. 예를 들면, IP 주소나 TCP/UDP의 포트번호 등이 빅 엔디언으로 표현됩니다. 이를 네트워크 바이트 순서(network byte order)라고 합니다. 한편, 대부분의 PC에서는 리틀 엔디언 형식을 사용하기 때문에 두 형식 간의 변환이 필요합니다.
따라서 네트워크를 통해 데이터를 송수신할 때는 보통 다음과 같은 과정을 거칩니다.
1. 송신자 측에서는 데이터를 네트워크 바이트 순서인 빅 엔디언으로 변환하여 전송합니다. 이때 htonl()
, htons()
와 같은 함수를 사용하여 호스트 바이트 순서(host byte order)에서 네트워크 바이트 순서로 변환합니다.
2. 수신자 측에서는 받은 데이터를 자신의 시스템 호스트 바이트 순서에 맞춰서 다시 해석합니다. 여기서도 ntohl()
, ntohs()
와 같은 함수들을 사용하여 네트워크 바이트 순서에서 호스트 바이트 순서로 변환합니다.
이런 변환 과정을 거치는 이유는 여러 종류의 컴퓨터 시스템이 각기 다른 엔디언 방식을 사용할 수 있는데, 네트워크 상에서 호환되는 방식으로 데이터를 읽고 쓸 수 있도록 하기 위함입니다. 따라서 일반적으로는 모든 변수를 빅엔디언으로 변환하여 전송하고, 이를 다시 수신자의 호스트 엔디언 형식으로 변환하여 사용하는 것이 일반적인 방법입니다.
Windows에서 소켓을 통해 데이터를 보낼 때 htonl()
을 사용하지 않고 구조체에 데이터를 그대로 넣어서 리틀 엔디언 채로 보내는 경우는 잘못된 방법일 수 있습니다. 송신과 수신에서 모두 빅 엔디언 혹은 리틀 엔디언을 사용해도, 두 시스템이 동일한 엔디언 방식을 사용하고 명시적으로 그렇게 사용하기로 합의가 되어 있지 않는 한, 일반적으로 네트워크 바이트 순서(빅 엔디언)을 사용하는 것이 좋습니다.
데이터를 송수신할 때의 엔디언 변환에 대해 더 자세히 알고 싶으시다면 관련 문헌이나 네트워크 프로그래밍 관련 자료를 참고하시는 것도 좋을 것 같습니다. 네트워크에서의 데이터 처리가 중요한 부분이므로, 신중하게 고려하여 개발하는 것이 필요합니다.
도움이 되셨길 바랍니다. 추가적인 질문이 있으시면 언제든지 질문해 주세요. 감사합니다.