바이트 순서와 네트워크 바이트 순서

네트워크 바이트 순서와 인터넷 순서가 어떤 관계가 있는지

시스템에 따라 Big Endian / Little Endian 사용 방식이 다르다.

Big Endian - 상위 바이트의 값을 작은 번지수에 저장

ex. 0x12345678 은 가장 낮은 번지부터 0x12 0x34 0x56 0x78 순서로 담긴다. (상위 바이트는 12이다.)


Little Endian - 상위 바이트의 값을 큰 번지수에 저장

ex. 0x12345678은 0x78 0x56 0x34 0x12 순서로 담긴다.


데이터 송수신 과정에서 데이터 저장방식의 차이 문제가 발생할 수 있음 따라서 네트워크 데이터 송수신을 할 땐 약속이 필요함

보내는 쪽, 받는 쪽 모두 BigEndian / LittleEndian이든 상관없이 보내는 바이트의 순서는 낮은 주소부터 전송(빅엔디안)한다는 것을 알려야한다.

네트워크 바이트 순서는 BigEndian 기준! (낮은 주소의 데이터 번지부터 전송!) 낮은 주소를 significant byte로 취급하라고 알려줌 )




바이트 순서의 변환

htons - host의 메모리 속 데이터 순서가 bigendian이든 littleendian이든 상관없이 network byte(bigendian) 타입으로 바꿔라


이식성을 위해서 변경되지 않는다 하더라도 변경을 취해준다!


0x1234에서 1 하나는 4bit이고 12가 1byte를 나타낸다.



문자열 정보를 네트워크 바이트 순서의 정수로 변환


inet_addr(const char* string)

( ).( ).( ).( ) 형태의 문자열을 4바이트의 정수 배열(in_addr_t: 32비트 정수형)로 바꿔주는 함수이다. 

성공 시 Big Endian으로 변환된 32비트 정수값

실패 시 INADDR_NONE 반환

또한 표현 가능 범위를 체크하여 비트 수를 초과하는 값의 변환을 시도하면 INADDR_NONE반환


inet_aton(const char* string, struct in_addr* addr);

기능상으로 inet_addr 함수와 동일하다. 다만 in_addr형 구조체 변수에 변환의 결과가 저장된다는 점에서 차이를 보인다.

(struct sockaddr_in 안에 struct in_addr형 sin_addr 변수/ struct in_addr 안에는 in_addr_t 타입 s_addr변수가 있음)

성공시 1(true), 실패 시 0(false) 반환


주로 inet_addr를 많이 사용. inet_aton을 지원하지 않는 경우가 많기 때문


inet_ntoa

32bit ip 주소를 ASCII형(. . . .)으로 변환


Note. 항상 네트워크 바이트 순서로 저장을 함 -> htonl 이용


inet_ntoa 에 (객체).sin_addr 를 인자로 넘김





인터넷 주소의 초기화


memset 을 하는이유 : sockaddr_in 구조체 변수의 마지막 8byte 변수는 사용하지 않기 때문에 모두 0으로 채울 필요가 있다.

(sockaddr_in 구조체 변수).sin_addr.s_addr = inet_addr(문자열 형태의 IP주소)   - 여기서 문자열 형태의 IP주소는 "( ).( ).( ).( )" 형태

atoi로 문자열을 정수형으로 변환

Q. 왜 s_addr에는 htons로 변경하지 않나 ?

inet_addr에서 자동적으로 big endian 형식의 32bit 정수형을 반환함


이렇게 초기화한 값을 bind에 할당하게 됨


서버에서 주소정보를 설정하는 이유! (초기화한 값을 bind의 인자로 넘긴 경우)

초기화한 IP, PORT로 들어오는 데이터는 내게로 다 보내라!


클라이언트에서 주소정보를 설정하는 이유(초기화한 값을 connect의 인자로 넘긴 경우)

초기화한 IP, PORT로 연결을 해라



INADDR_ANY

현재 실행중인 컴퓨터의 IP를 소켓에 부여할 때 사용되는 것이 INADDR_ANY이다.

이는 서버 프로그램의 구현에 주로 사용된다.

이때 htonl(INADDR_ANY)형태로 대입한다.

4Byte unsigned int로 들어가 있으므로 데이터 순서만 정렬해서 넣어줌


이미 정해진 것을 사용하겠다는 의미

그러나 컴퓨터에 network interface card가 두개가 있을 땐 직접 지정해줘야 한다.

이때 INADDR_ANY를 쓰면 어느 것이 들어갈 지 모른다.


'CS & IT실무' 카테고리의 다른 글

IO 멀티플렉싱  (0) 2018.11.13
Half-Close - shutdown()  (0) 2018.10.05
소켓에 할당되는 IP주소와 PORT번호  (0) 2018.10.04