(C언어) network byte order, float 변환 함수 구현 (ntohf, htonf)

2024. 1. 15. 19:54코딩세상/C-언어

인터넷 설정을 하다 보면 network이라는 문구를 많이 보게 된다.

network이라는 것을 어렵게 생각하지 말고 인간관계에서 친구라고 보면 된다.

 

친구들도 속성이 다 달라서 규칙을 정하지 않으면 소통에 오류가 생기게 된다.

 

인터넷에서 제일 중요한 data를 주고받는 방법이 필요한데, 이를 정의한 것이 byte order이라는 것이 있다.

현재 network 통신에서는 기본적으로 big endian을 사용하도록 되어 있다.

 

big endian, little endian이 뭔지 생각 하지 말고, network으로 통신 시에는 무조건 big endian으로 맞추어 줘야 한다는 것을 기억하자.

 

네트워크는 byte 단위로 data가 전송이 되는데, 2bytes 이상에서는 먼저 전달되는 data가 큰 쪽인지 작은 쪽인지 구분을 해야 한다. 이것을 정하는 것이 byte order다.

 

조금 어렵게 느껴진다.. 그럼 언제 바꿔줘야 하지???

 

2bytes 이상 되는 data는 무조건 변환하여 사용하도록 하자.

 

linux의 man page를 보면 지원하는 byte order가 아래와 같다.

친절하게 header file까지 같이 알려 준다.

 

다음 명령어를 입력하자.

man ntohs

여기에서 보면 float에 관련된 함수가 없다.

linux에는 없다. float를 써야 하는데, 어떻게??

 

없으면 구현해 주자.

float는 4 bytes이다.

4 bytes 변환을 해 주는 함수로 ntohl, htonl 이 있다. 해당 함수를 이용하여 변환해 주자.

 

어떻게 할 것인가???

 

2가지 방법이 있다.

 - union 사용 : 하나는 변수에 있는 값을 다르게 사용할 수 있다

-  포인터 사용 : uint32_t * 형으로 주소를 받아 사용.

 

union 방식

 

포인터 사용 방식

 

아래는 test 프로그램이다.

 

bytes의 순서가 바뀌는 것을 확인할 수 있을 것이다.

 

아래 소스 참조하세요.

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

#define UNION_TYPE

#ifdef UNION_TYPE
typedef union {
    float    f;
    uint32_t u;
} conv_byte_f;

float ntohf(float f)
{
    conv_byte_f conv;

    conv.f = f;
    conv.u = ntohl(conv.u);

    return conv.f;
}
#else
float ntohf(float f)
{
    uint32_t *p;

    p = (uint32_t *)&f;
    *p = ntohl(*p);

    return f;
}
#endif

int main()
{
    unsigned char *p;
    int i;

    float in = 1234.56;

    p = (unsigned char *)&in;

    for (i = 0; i < 4; i++)
        printf("%02X ", *(p + i));

    printf("\n");

    in = ntohf(in);

    for (i = 0; i < 4; i++)
        printf("%02X ", *(p + i));

    printf("\n");
}