함수설명

#include <arpa/inet.h>

/* host to network long */
uint32_t htonl(uint32_t hostlong);

/* host to network short */
uint16_t htons(uint16_t hostshort);

/* network to host long */
uint32_t ntohl(uint32_t netlong);

/* network to host short */
uint16_t ntohs(uint16_t netshort);

 

Computer(host)의 byte order는 OS나 CPU의 종류에 따라 다르며 주요 byte order로는 big endian, little endian 등이 있다.

network byte order는 big endian이다. 따라서 network에 필요한 port번호 등을 설정하는 경우에는 network byte order로 설정해야 하며, 그것을 local computer에서 출력하거나 할 때에는 computer(host)의 byte order로 변환해서 출력해야한다. x86계열은 little endian이며, UNIX 계열의 시스템은 종류에 따라 다르지만 일반적으로 big endian이다.

 

short int value = 0x1234;

C언어의 변수에 저장되어 있을 경우 

little endian이면 메모리에 0x3412로 저장되어 있으며, big endian은 메모리에 0x1234로 저장됩니다.

 

이 때문에 Computer마다 데이터의 저장 위치가 달라서 정수형 데이터 전송시 다른 시스템에서는 다른 값으로 인식될 수 있다. 이를 방지하기 위해서 통신에서는 데이터부의 숫자를 문자열로 변환해서 보내는 경우가 일반적이다. 그렇지만 network protocol과 같은 부분에서는 network byte order인 big endian으로 변환해야 한다.

 

htonl : host to network long int

htons : host to network short int

ntohl : network to host long int

ntohs : network to host short int

함수 이름의 의미이며, long int는 16bit 시절에 만들어져서 long은 32bit값입니다. 여기서 host는 현재 실행되고 있는 컴퓨터 자신을 의미한다.

 

 


활용예제

 

#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define SERVER_PORT   6905
#define SERVER_NAME   "job.mydomain.com"

......

struct hostent *he;
struct sockaddr_in server_addr;
int  sock;

......

if((he = gethostbyname(SERVER_NAME)) == NULL) {
    fprintf(stderr, "%s는 등록되지 않은 서버명입니다.\n", SERVER_NAME);
    return -1;
}

memset(&server_addr, 0x00, sizeof(struct sockaddr_in));
server_addr.sin_samily = AF_INET;

memcpy(server_addr.sin.sin_addr, he->h_addr, he->h_length);
// port 변호는 network byte order를 따라야 하므로 htons사용
server_addr.sin_port   = htons(SERVER_PORT); 
     


if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    fprintf(stderr, "Socket 생성 오류: %s\n", strerror(errno));
    return -1;
}

if(connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) == -1) {
    fprintf(stderr, "Connection Error: %s\n", strerror(errno));
    close(sock);
    return -1;
}

......

 


see also : Socket 통신과 Socket 응용

 

 

 

 

블로그 이미지

자연&사람

행복한 개발자 programmer since 1995.

Tag , ,

댓글을 달아 주세요