2012-10-19 3 views
2

변수 '값은'htonl 인쇄 쓰레기 값

value = htonl(value); 

    printf("after htonl is %ld\n\n",value); 

    This prints -201261056 

    value = htons(value); 

    printf("after htons is %ld\n\n",value); 

    This prints 62465 

이 이유가 될 수있는 것을 제안하십시오 uint32_t입니까?

+0

** 16) ==는 '%의 ld'은'서명 long'를 인쇄하다 많은 시스템에서 8 바이트 유형입니다. 'stdint.h'를 포함하고'uint32_t'에'PRIu32'를 사용하십시오. –

답변

2

나는 그것이, 귀하의 의견은 500되지 않는 것 같아요?

500 2 * 8 + 2 * 7 * 2 + 6 + 2 * 2 * 5 + 4 + 2 * 2 또는 리틀 엔디안 순서 0x00 0x00 0x01 0xF4.

TCP/IP는 빅 엔디안을 사용합니다. 그래서 htonl 다음에 시퀀스는 0xF4 0x01 0x00 0x00입니다.

부호있는 정수로 인쇄하는 경우 첫 번째 숫자는 1이므로 음수입니다.음수 보체로 간주되며,이 값은 - (2 * 27 + 2 * 25 + 2 * 24 + 2 * 23 + 2 * 22 + 2 * 21 + 2 * 20 + 2 * 19 + 2 * 18 + 2 * 17 + 2 당신은 잘못된 형식 지정자를 사용하고 -201261056

+1

@halflef, 네가 맞아, 내 입력은 500이야. – user1727270

1

주최자 주문은 컴퓨터가 리틀 엔디안이라고 가정하고 데이터를 올바르게 이해하는 순서입니다. 네트워크 주문은 시스템에서 제대로 이해할 수없는 Big Endian입니다. 이것이 소위 쓰레기 값의 이유입니다.

기본적으로 코드에는 아무 것도 없습니다. :)

Google Big Endian 및 Little Endian에 대한 모든 세부 정보를 얻으려면 "Endianness"

빅 엔디안에서 첫 번째 바이트 또는 가장 낮은 주소는 가장 중요한 바이트를 가지며 리틀 엔디안에서 같은 위치에 최하위 바이트가 나타납니다. 따라서 htonl을 사용할 때 첫 번째 바이트에는 최상위 바이트가 포함되지만 시스템에서는 최하위 바이트로 간주합니다.

big 엔디안에서 위키 백과 예제 1000 (hex 3E8)을 고려하면 03 E8이 될 것이고 리틀 엔디안에서는 E8 03이 될 것입니다. 이제 03 E8을 작은 시스템에 전달하면 소수점 이하 59395

+1

아니요, 호스트 순서는 * 호스트 순서 *를 의미합니다. 리틀 엔디안 또는 빅 엔디안이 아니라 호스트가 사용하는 순서입니다. 리틀 엔디안 일 수도 있고, 빅 엔디 언일 수도 있고, 타임 머신을 사용하는 경우 [중간 엔디 언] 일 수도 있습니다 (http://en.wikipedia.org/wiki/Endianness#Middle-endian). . – unwind

+0

@unwind, 죄송합니다. 그 쪽이 맞는 거 같아요. 이것을 반영하기 위해 내 대답을 수정했습니다. 그러나 나는 아직도 그 문제를 해결할 수 있다고 생각한다. 내 대답에 오류가 있다고 생각되면 언제든지 지적하거나 수정하십시오. 감사. :) – Jay

1

htonl() and htons()은 호스트의 endianess에서 network endiness로 데이터를 변환하는 데 사용되는 함수입니다.

네트워크에서 빅 엔디안을 사용합니다. 그래서 시스템이 X86이면 리틀 엔디안입니다.

호스트 간 네트워크 바이트 순서 (긴 데이터)는 htonl()입니다. 즉 32 비트 값을 네트워크 바이트 순서로 변환합니다.

호스트 간 네트워크 바이트 순서 (짧은 데이터)는 htons()입니다. 즉 16 비트 값을 네트워크 바이트 순서로 변환합니다.

htonl() 함수가 htons() 함수에서 32 비트 값을 사용하는 효과뿐만 아니라 htmll()이 어떻게 작동하는지 보여주는 샘플 프로그램.

#include <stdio.h> 
#include <arpa/inet.h> 

int main() 
{ 
    long data = 0x12345678; 
    printf("\n After htonl():0x%x , 0x%x\n", htonl(data), htons(data)); 
    return 0; 
} 

X86_64에 After htonl():0x78563412 , 0x7856이 인쇄됩니다.

참조 :

http://en.wikipedia.org/wiki/Endianess

http://msdn.microsoft.com/en-us/library/windows/desktop/ms738557%28v=vs.85%29.aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/ms738556%28v=vs.85%29.aspx

0
@halfelf>I jut want to put my findings.I just tried the below program with the same 
value 500.I guess you have mistakenely mentioned output of LE as BE and vice versa 
Actual output i got is 0xf4 0x01 0x00 0x00 as little Endian format.My Machine is 
LE 
#include <stdio.h> 
#include <netinet/in.h> 
/* function to show bytes in memory, from location start to start+n*/ 
void show_mem_rep(char *start, int n) 
{ 
    int i; 
    for (i = 0; i < n; i++) 
     printf(" %.2x-%p", start[i],start+i); 
    printf("\n"); 
} 

/*Main function to call above function for 0x*/ 
int main() 
{ 
    int i = 500;//0x; 
    int y=htonl(i); --->(1) 
    printf("i--%d , y---%d,ntohl(y):%d\n",i,y,ntohl(ntohl(y))); 
    printf("_------LITTLE ENDIAN-------\n"); 
    show_mem_rep((char *)&i, sizeof(i)); 
    printf("-----BIG ENDIAN-----\n");/* i just used int y=htonl(i)(-1) for reversing 
    500 ,so that 
    i can print as if am using a BE machine. */ 

    show_mem_rep((char *)&y, sizeof(i)); 

    getchar(); 
    return 0; 
    } 
output is 
i--500 , y----201261056,ntohl(y):-201261056 
_------LITTLE ENDIAN------- 
f4-0xbfda8f9c 01-0xbfda8f9d 00-0xbfda8f9e 00-0xbfda8f9f 
-----BIG ENDIAN----- 
    00-0xbfda8f98 00-0xbfda8f99 01-0xbfda8f9a f4-0xbfda8f9b