본문 바로가기
Programming/Linux C/C++

주소체계와 데이터 정렬

by 개Foot/Dog발?! 2014. 8. 29.

URL : http://christin2.tistory.com/27


.....


- IPv4 기준의 4바이트 IP주소는 네트워크 주소와 호스트 주소로 나뉨

- 주소의 형태의 따라서 A, B, C, D, E 클래스로 분류


클래스 A의 첫 번째 바이트 범위 : 0이상 127 이하 - 클래스 A의 첫 번째 비트는 항상 0으로 시작

클래스 B의 첫 번째 바이트 범위 : 128이상 191 이하 - 클래스 B의 첫 번째 비트는 항상 10으로 시작

클래스 C의 첫 번째 바이트 범위 : 192이상 223 이하 - 클래스 C의 첫 번째 비트는 항상 110으로 시작


- 네트워트 주소(Network ID) : 네트워크의 구분을 위한 IP 주소의 일부를 의미



IP주소 기반의 데이터 전송과정

1. IP주소 중에서 네트워크 주소만을 참조해서 해당 네트워크로 데이터 전송

(네트워크를 구성하는 라우터 또는 스위치로 데이터가 전송됨)


2. 데이터를 전송 받은 라우터는 데이터에 적혀있는 호스트 주소를 참조하여 데이터 전송



PORT 번호

- 컴퓨터 내부로 전송된 데이터를 운영체제가 PORT 번호를 활용하여 소켓에 분배

- 소켓을 구분하는 목적

- 범위 : 0 ~ 65535

- Well-known PORT(예약포트) : 0 ~ 1023

- PORT 번호는 중복이 불가능하지만 TCP소켓과 UDP소켓은 PORT번호를 공유하지 않기 때문에 중복되어도 상관없음


IPv4 기반의 주소표현을 위한 구조체 


ref URL : http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/15/sockaddr


* sin_family

ref URL : http://korean-coder.blogspot.kr/2014/04/c_5.html

ref URL : http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/TCP_IP/IPv6/IPv6Prog


* sin_port

- 16비트 PORT번호를 저장

- 네트워크 바이트 순서로 저장


* sin_addr

- 32비트 IP주소정보 저장

- 네트워크 바이트 순서로 저장

 

* sin_zero

- 반드시 0으로 채우기

 


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

빅 엔디안 : 상위 바이트의 값을 작은 번지수에 저장하는 방식

리틀 엔디안 : 상위 바이트의 값을 큰 번지수에 저장하는 방식(Intel계열 CPU)


- CPU의 데이터 저장방식을 의미하는 '호스트 바이트 순서'는 CPU에 따라서 차이가 남


* 네트워크 바이트 순서를 '빅 엔디안 방식'으로 통일

 


바이트 순서의 변환(Endian Conversion)

unsigned short htons(unsigned short);

unsigned short ntohs(unsigned short);

unsigned long htonl(unsigned long);

unsigned short ntohl(unsigned long);


ref URL : http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/3/htons

- htons에서 h는 호스트 바이트 순서, n은 네트워크 바이트 순서

- htons : short형 데이터를 호스트 바이트 순서에서 네트워크 바이트 순서로 변환

- ntohs : short형 데이터를 네트워크 바이트 순서에서 호스트 바이트 순서로 변환

- s가 붙는 함수는 PORT번호 변환에 사용

- l이 붙는 함수는 IP주소 변환에 사용


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

ref URL : http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/3/inet_addr


- 함수의 인자로 점이 찍힌 10진수로 표현되 문자열을 전달하면 해당 문자열 정보를 참조해서 IP주소 정보를 32비트 정수형 으로 반환

- 반환되는 정수는 네트워크 바이트 순서로 정렬

- 오류검출 능력도 갖음

- 이 함수 사용시, 변환된 IP주소 정보를 구조체 sockaddr_in에 선언되어 있는 in_addr 구조체 변수에 대입하는 과정을 추가   로 거쳐야 함

- inet_aton 함수와 기능상 동일

ref URL : http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/3/inet_addr

- string : 변환할 IP주소 정보를 담고 있는 문자열의 주소 값 전달

- addr : 변환된 정보를 저장할 in_addr 구조체 변수의 주소 값 전달

- 별도의 대입과정 없음


ref URL : http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/3/inet_addr

- 네트워크 바이트 순서로 정렬된 정수형 IP주소 정보를 문자열의 형태로 변환

- 반환형이 char형 포인터라는 것은 문자열이 메모리공간에 저장되었다는 뜻

- 함수가 재 호출되기 전까지만 반환된 문자열의 주소 값이 유효하니, 문자열 정보를 유지하려면 별도의 메모리공간에 복사할 것



인터넷 주소의 초기화


- memset 함수는 동일한 값으로 바이트단위 초기화 할 때 호출하는 함수

- memset함수로 addr을 전부 0으로 초기화하는 이유는 0으로 초기화 해야하는 sockaddr_in 구조체 멤버 sin_zero를 0으로  초기화하기 위함

- 문자열로 표현된 IP주소와 PORT번호를 기반으로 하는 sockaddr_in 구조체 변수의 초기화 과정


* INADDR_ANY

ref URL : https://kldp.org/node/42146

: 소켓이 동작하는 컴퓨터의 IP주소가 자동으로 할당됨

: 컴퓨터 내에 두 개 이상의 IP를 사용하는 경우 할당 받은 IP중 어떤 주소를 통해서 데이터가 들어오더라도 PORT 번호만    일치하면 수신 가능


 소켓에 인터넷 주소 할당하기

ref URL : http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/2/bind

- 초기화된 주소정보를 소켓에 할당

- sockfd : 주소정보를 할당할 소켓의 파일 디스크립터

- myaddr : 할당하고자 하는 주소정보를 지니는 구조체 변수의 주소값

- addrlen : 두 번째 인자로 전달된 구조체 변수의 길이 정보

 

- WSAStringToAddress : 주소정보를 나타내는 문자열을 가지고 주소정보 구조체 변수를 채워 넣을 때 호출하는 함수

- WSAAddressToString : 구조체 변수에 저장된 데이터를 참조하여 주소정보를 담고 있는 문자열을 만들어서 반환