Tuesday, July 13, 2010

chapter 3 (주소체계와 데이터 정렬)

IP : internet protocol, 데이터의 송수신을 위해 컴퓨터에 부여하는 값
PORT 번호 : 프로그램에서 생성되는 소켓을 구분하기 위해 소켓에 부여되는 번호

-소켓에 할당되는 IP주소와 PORT번호-


인터넷 주소(Internet Address, IP 주소) : IPv4 (4바이트 주소 체계), IPv6 (6 바이트 주소체계), IPv6는 IP가 부족할것을 고려해 만든 체계이나 아직 IPv4가 대세. IPv4는 그림과 같이 A~E 클래스로 분류된다. E 클래스는 일반적이지 않고 예약되어 있다. 그림에서 나오는 네트워크 주소 (network ID) 란 네트워크 구분의 위한 IP주소의 일부. 예를 들어 데이터를 203.211.172.103의 컴퓨터로 전송한다고 할때 우선은 IP주소의 네트워크 ID (여기서는 203.211.172)로 데이터를 보내고 라우터(네트워크 안의 호스트와 외부의 데이터 송수신을 위한 물리적 장치)가 나머지 호스트 ID (여기서는 172)로 데이터를 전송한다.


IP 주소의 클래스 구분법 : 
클래스 A 의 첫 바이트 범위 0 ~ 127
클래스 B 의 첫 바이트 범위 128 ~ 191
클래스 C 의 첫 바이트 범위 192 ~ 223


소켓의 구분에 활용되는 PORT번호 : IP는 컴퓨터를 구분하기 위한 값이다. 이런 IP를 보고 전달된 데이터는 컴퓨터의 수많은 프로그램 중에 어떤 프로그램에 사용되어야 하는지 구분되어지기 위해 사용되는 것이 PORT번호이다. 이 PORT번호를 통해 운영체제가 해당 소켓에 데이터를 분배한다. 즉 하나의 운영체제 내에서 소켓을 구분하기 위한것이 PORT 번호이다. 16 비트 (0~65535)이다. 중복되어선 안되며 0~1023는 well-known PORT라고 해서 특정 프로그램에 할당되어져 있기에 이를 제외해서 사용한다.



-주소정보의 표현-


IPv4 기반의 주소표현을 위한 구조체 : 주소정보에는 프로토콜 체계 (예: IPv4), IP 주소, PORT 번호가 들어가 있어야 한다.
오른쪽 구조체에 사용된 자료형과 멤버는 책을 참조. 매우 중요




-네트워크 바이트 순서와 인터넷 주소 변환-


이부분의 위의 주소정보표현의 구조체인 sockaddr_in의 멤버 sin_port와 sin_zero를 위한 것이다.
CPU마다 메모리에 데이터를 저장하고 해석하는 방식이 다르다(호스트 바이트 순서).
빅 엔디안 (Big Endian) : 상위 바이트의 값을 작은 번지수에 저장하는 방식
리틀 엔디안 (Little Endian) : 상위 바이트의 값을 큰 번지수에 저장하는 방식, 대표적으로 intel 계열의 CPU
그래서 CPU마다 다른 방식으로 데이터 저장 방식(호트스 바이트 순서)이 다르므로 이를 통일하고 한것이 "네트워크 바이트 순서"로 빅 엔디안을 뜻한다.
바이트 순서를 변환해주는 함수:
unsigned short htons(unsigned short);
unsigned short ntons(unsigned short);
unsigned long htonl(unsigned long);
unsigned long ntonl(unsigned long);
htons 에서 h는 host를 s는 short를 의미, 즉 htons(h to n s)는 PORT번호(short형 데이터) 를 호스트 바이트 순서에서 네트워크 바이트 순서로 변환하라는 의미



-인터넷 주소의 초기화와 할당-


다음은 코드 설명이 많으므로 책 참조
문자열 정보를 네트워크 바이트 순서의 정수로 변환하기 : 우리가 익숙한 IP 주소는 점이 찍힌 십진수 표현 방식 (Dotted-Decimal Notation)으로 이를 32비트 정수형으로변환해주는 함수가 필요한데 이것이 inet_addr와 inet_aton이다. 차이점은 inet_addr는 성공시 in_addr_t (unsigned 32 bit int)를 실패시 INADDR_NONE을 반환하는 반면,  inet_aton은 성공시 1을 실패시 0을 반환하고 매개변수로 구조체인 in_addr의 주소를 받아서 성공시 그곳에 변환된 값을 넣는다.
inet_aton과 반대 역활, 그러니까 32비트 정수형으로 되어 있는 IP를 Dotted-Decimal Notation으로 변환해 주는 함수가 inet_ntoa이다.


인터넷 주소의 초기화 : 아래 그림 참조


클라이언트의 주소정보 초기화 : 클라이언트의 connet 함수 역시 구조체 sockaddr_in를 사용하나 IP와 PORT의 대상이 다르다. 서버 bind 함수의 경우 서버의 IP와 PORT를, 클라이언트의 connect 함수의 경우 서버의 IP와 PORT를 넣어야 한다.
서버의 경우 "IP 211.217.168.13 PORT 9190으로 들어오는 데이터는 내게 보내라"
클라이언트의 경우 "IP 211.217.168.13 PORT 9190으로 연결해라" 라는 의미


INADDR_ANY : 위에서 처럼 매번 bind 함수에 IP를 넣는 것이 귀찮기 때문에 자동화로 IP를 받을 수 있다. 위에 그림에서 serv_ip를 선언하지 말고 addr.sin_addr.s_addr=inet_addr(serv_ip); 대신 
addr.sin_addr.s_addr=htonl(INADDR_ANY); 라고 하면 자동으로 IP가 할당된다.


서버소켓 초기화 과정 : 소켓선언과 함께 위 내용을 최종 정리하면 다음 그림과 같다(1장에서 3장까지의 내용 총괄).

No comments:

Post a Comment