본문 바로가기

네트워크 프로그래밍

TCP / IP 소켓 프로그래밍 -3-

주소체계와 데이터 정렬

 

Internet Address

 

IP주소란 인터넷상에 존재하는 호스트들을 구분하기 위한 32비트 주소 체계를 말한다.

일반적으로 점이 찍힌 십진수 표현 방식을 사용해서 IP주소를 표현하는데, 점에 의해 구분되는 각각의 십진수 값은 1바이트이다.

따라서 총 4바이트(32비트)를 사용하게 된다.

 

Port?

 

IP주소만으로는 수신한 데이터 패킷(네트워크상에서 이동하는 데이터 블록을 총칭)을 어떤 프로세스에 전달해줄지 모른다.

이를 위해 필요한 것이 Port이다. 32비트 IP주소로는 네트웤상에 존재하는 호스트를 구분하게 되고, 16비트 Port정보로는

호스트 내에 실행되고 있는 프로그램을 구분하게 된다. 이것은 물리적(하드웨어적)이 아닌 논리적(소프트웨어적) 할당이다.

☞프로세스 : 하드디스크에 저장되어 있는 프로그램 자체가 아니라 메인 메모리에 올라와서 실행되고 있는 프로그램.

 

주소 정보의 표현

 

IPv4의 주소 구조체

struct sockaddr_in{

           sa_family_t        sin_family          // 주소 체계

           uint16_t sin_port // 16 비트 TCP

           struct in_addr    sin_addr // 32비트 IPv4 조소

           char                sin_zero[8]        // 사용되지 않음

};

sin_family : 프로토콜 체계마다 주소 체계가 다르기 때문에 정보를 대입해준다.

           1)AF_INET  : IPv4 인터넷 프로토콜

           2)AF_INET6 : IPv6 인터넷 프로토콜

           3)AF_LOCAL : Local 통신을 위한 UNIX 프로토콜

sin_port : 16비트 Port 정보를 네트워크 바이트 순서대로 대입.

sin_addr : 32비트 IP주소 정보를 네트워크 바이트 순서대로 대입.

sin_zero : 특별한 의미 없이 단순히 채워주기 위한 목적으로 사용

 

네트워크 버이트 순서?

 

바이트 순서란 시스템이 내부적으로 데이터를 표현하는 방법이다. 하지만 모든 시스템의 데이터 표현방식이 같은 것은 아니다.

하나는 Big-Endian방식이고, 다른 하나는 Little-Endian방식이다.

시스템이 내부적으로 데이터를 처리하는데 있어서 어떤 방식을 쓰느냐는 시스템의 CPU에 따라 달라진다.

이를 호스트 바이트 순서(HOST BYTE ORDER)라고 하는데 이는 일정치 않다는 것이 문제다.

이는 CPU가 다른 두 호스트 간에 데이터를 보내면 서로 다른 값으로 해석된다.

이러한 문제점 때문에 네트워크를 통해 데이터를 전송할 때는 통일된 방식을 이용해서 테이터를 전송하기로 약속.

이를 네트워크 바이트 순서(NETWORK BYTE ORDER)라고 한다.

네트워크 바이트 순서는 Big-Endian방식만 쓴다.

 

0x12345678를 표현.

 1) Big-Endian방식

          

           | 0x12 | 0x34 | 0x56 | 0x78 |                    // --->쪽으로 메모리번지가 증가

    상위 바이트의 값이 메모리 상에 먼저(번지수가 작은 위치에) 표시되는 방식.

 

 2) Little-Endian방식

          

           | 0x78 | 0x56 | 0x34 | 0x12 |                    // --->쪽으로 메모리번지가 증가

    하위 바이트의 값이 메모리상에 먼지(번지수가 작은 위치에) 표시되는 방법이다.

 

 

 

바이트 순서 변환(Endian Conversions)

 

바이트 순서 변환 함수

h : host byte order

n : network byte order

s : short (16bit)

l : long  (32bit)

 

htonl?

h to n, l type : 32비트 데이터(l type)를 호스트 바이트 순서(h)에서 네트워크 바이트 순서(n)로 바꿔주는 함수.

 

인터넷 주소 조작하기

 

1) inet_addr(const char *string)

           십진수로 표현된 주소값(점이 있는) Big-Endian 32비트 값으로 변환

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

           inet_addr 업그레이드 버젼.

3) inet_ntoa(struct in_addr addr)

           네트워크 바이트 순서로 표현된 32비트 값을 십진수 주소값으로 변환하는 함수

 

인터넷 주소 초기화

 

struct sockaddr_in addr;

char *serv_port = "9000";

memset(&addr,0,sizeof(addr_len));  //memset 함수를 호출하여 인자로 전달된 구조체 변수를 0으로 초기화.

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = htonl(INADDR_ANY);   // INADDR_ANY상수를 통해 현재 시스템의 IP주소를 자동적으로 찾아 할당.

addr.sin_port = htons(atoi(serv_port));

 

소켓에 주소 정보 할당하기

 

int bind(int sockfd, struct sockaddr *myaddr, int addrlen);  // 실패시 -1 리턴

sockfd  : 주소를 할당하고자 하는 소켓의 파일 디스크립터를 인자로 전달

myaddr  : 할당하고자 하는 주소정보를 지니고 있는 sockaddr_in 구조체 변수의 포인터를 인자로 전달

addrlen : 인자로 전달된 주소 정보 구조체의 길이를 전달