htons의 혼란 - 리틀 엔디안/빅 엔디안
-
16-09-2019 - |
문제
소켓을 통해 한 프로세스에서 다른 프로세스로 정수 변수를 보낸 다음 수신된 끝에 값을 인쇄하면 ntohl/htonl을 사용하지 않고도 값이 여전히 동일합니다. 그러면 소켓 구조를 초기화하는 것 외에 이러한 함수를 어디에서 사용해야 합니까?나는 litte/big endian을 이해합니다.그런데 값이 동일하게 유지되는 경우 포트 및 IP 번호를 호스트/네트워크 바이트 순서로 변환해야 하는 이유는 무엇입니까?정수가 네트워크를 통해 어떻게 전송되는지 자세히 설명해주세요.
해결책
프로그램을 이식 가능하게 하려면 네트워크를 통해 크기가 1바이트보다 큰 정수를 보낼 때마다 먼저 다음을 사용하여 이를 네트워크 바이트 순서로 변환해야 합니다. htons
또는 htonl
, 수신 컴퓨터는 다음을 사용하여 이를 호스트 바이트 순서로 변환해야 합니다. ntohs
또는 ntohl
.
귀하의 경우 값이 여전히 동일한 이유는 송신 컴퓨터와 수신 컴퓨터의 엔디안이 동일하기 때문일 수 있습니다.즉, 작업 중인 송신 컴퓨터와 수신 컴퓨터는 모두 리틀 엔디안(또는 경우에 관계없이 빅 엔디안)입니다.
그러나 프로그램을 이식 가능하게 만들고 싶다면 항상 그렇다고 믿을 수는 없습니다.예를 들어 어느 날 송신 컴퓨터는 Intel x86이고 수신 컴퓨터는 Sun SPARC일 수 있으며, 이를 사용하지 않으면 프로그램이 실패하게 됩니다. htons
.
다른 팁
x86 또는 amd64 시스템에서 PowerPC 프로세서가 있는 시스템으로 데이터를 보내려면 바이너리 형식을 지정하면 서로 다른 프로세서가 정수를 다르게 처리하고 바이트를 교환하는 것처럼 보이기 때문에 데이터에 "NUXI 문제"가 발생한다는 것을 빨리 알 수 있습니다.(실제로 바이트를 교환하지는 않습니다. 단지 다른 순서로 작업할 뿐입니다.)
x86 또는 amd64에서 작업할 때 최하위 바이트가 메모리에서 먼저 옵니다(이렇게 하면 더 낮은 메모리 주소에서 더 높은 메모리 주소로 추가를 수행할 수 있습니다).PowerPC는 가장 중요한 바이트를 메모리에 먼저 넣습니다(이 방법을 사용하면 메모리에서 먼저 나오는 바이트를 기준으로 숫자를 정렬할 수 있습니다. 문자열 정렬과 정수 정렬은 정확히 동일할 수 있습니다.)
아키텍처에서 네트워크 순서가 기본 순서와 동일하기 때문에 동일하게 유지됩니다.다른 아키텍처에 대한 코드를 컴파일할 것으로 예상하지 않는다면 hton/ntoh 호출을 생략할 수 있습니다.그러면 코드를 이식할 수 없습니다.