TCP/IP 소켓 프로그래밍 03. 주소 체계와 데이터 정렬  시스템프로그래밍 

2013.03.15. 23:21  수정  삭제

복사http://blog.naver.com/pwk0810/40183967503

전용뷰어 보기

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

 

IP 는 Internet protocol 의 약자로 인터넷 상에서 데이터를 송수신 할 목적으로 컴퓨터에게 부여하는 값을 의미.

 

PORT 는 컴퓨터에게 부여하는 값이 아닌, 프로그램 상에서 생성되는 소켓을 구분하기 위해 소켓에 부여되는 번호를 뜻한다.

 

+ 인터넷 주소(Internet Address )

 

 

  • IPv4( Internet Protocol version 4 ) :4 바이트 주소 체계
  • IPv6 (Internet Protocol version 6) : 16 바이트 주소 체계

 

 

 

  • IPv4 와 IPv6 의 차이점은 IP주소의 표현에 사용되는 바이트의 크기에 있다.
  • IPv4 기준의 4바이트 IP 주소는 네트워크 주소와 호스트 주소로 나뉘며, 주소의 형에 따라서 A,B,C,D ,E 클래스로 분류가 된다.

  • WWW.000.COM 의 000 에게 데이터를 전송한다고 가정해 보면 
    • 처음부터 4바이트의 IP 주소를 전부 참조해서 000의 컴퓨터로 데이터가 전송되는 것이 아니라 4바이트 ip 주소 중에서 네트워크 주소만을 참조해서 일단 000.COM 의 네트워크로 데이터가 전송.
    • .COM 의 네트워크로 데이터가 전송되었다면, 해당 네트워크 는 전송된 데이터의 호스트 주소 (HOST ID)를 참조하여 000의 컴퓨터로 데이터를 전송해 준다.
    • 네트워크로 데이터가 전송된다는 것은 네트워크로 구성하는 라우터 또는 스위치 로 데이터가 전송됨을 뜻함.
  • 라우터와 스위치
    • 네트워크를 구성하려면 , 외부로 부터 수신된 데이터를 호스트에 전달하고 호스트가 전달하는 데이터를 외부로 송신해주는 물리적 장치가 필요.
    • 이것이 라우터와 스위치이다. 

+ 클래스 별 네트워크 주소와 호스트 주소의 경계
  • 클래스 A의 첫번째 바이트 범위  : 0이상 127 이하
  • 클래스 B의 첫번째 바이트 범위 : 128 이상 191 이하
  • 클래스 C의 첫번째 바이트 범위 : 192 이상 223 이하

  • 클래스 A의 첫번째 비트는 항상 0으로 시작
  • 클래스 B의 첫두 비트는 항상 10으로 시작
  • 클래스 C의 첫 세비트는 항상 110 으로 시작

+ 소켓의 구분에 활용되는 PORT 번호
  • 둘이상의 컴퓨터로 부터 데이터를 전송받으려면 둘이상의 소켓이 생성되어야 한다.
  • 하나의 운영체제 안에서 소켓을 구분하는 목적으로 사용되기 때문에 하나의운영체제 내에서 동일한  PORT 번호를 둘 이상의 소켓에 할당할 수 없다.
03-2. 주소 정보의 표현

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

struct sockaddr_in
{
sa_family_t       sin_family ;     // 주소 체계
uint16_6           sin_port;        // 16비트 TCP/UDP PORT 번호;
struct              sin_addr;       // 32비트 IP 주소
char                sin_zero[8];  // 사용되지 않음

};

struct in_addr
{
in_addr_t s_addr;   // 32비트 IPv4 인터넷 주소
};

+구조체 sockaddr_in 의 멤버에 대한 분석

  • 멤버  sin_family ( 주소 정보 체계 : AF_INET, AF_INET6 , AF_LOCAL )
  • 멤버 sin_port : 16bit port 번호를 저장 ( 네트워크 바이트 순서 ) 

  • struct sockaddr_in serv_addr;
  • if(bind(serv_sock, (sturct sockaddr*) &serv_addr, sizeof(serv_addr)) == -1) 
  • struct sockaddr{
    • sa_family_t sin_family;
    • char sa_data[14];
    • };

03-3.  네트워크 바이트 순서와 인터넷 주소 변환
+ 바이트 순서( Order) 와 네트워크 바이트 순서

  • big endian ( 상위 바이트의 값을 작은 번지수에 저장하는 방식)
  • little endian  (상위 바이트의 값을 큰 번지수에 저장하는 방식 ) - 인텔 계열ㅂ
  • 빅엔디안 0x12 , 0x34의 조합으로 만들어 지는 값은 리틀 엔디안 에서 0x34, 0x12 의 조합으로 만들어지는 값과 같다.
  • 데이터 전송시 바이트 순서에 대한 혼란을 막기 위해 네트워크 바이트 순서를 통일하였다.
  • 빅엔디안 방식으로 통일
  • 모든 시스템 ( 특히 리틀 엔디안 ) 은 데이터를 전송하기에 앞서 빅엔디안의 정렬 방식으로 데이터를 재 정렬 해야 한다.

+ 바이트 순서의 변환( Endian Conversions)
  • unsigned short htons( unsigned short ) ;
  • unsigned short ntohs( unsigned short );
  • unsigned long htonl( unsigned long );
  • unsigned log ntohl( unsigned long );
  • htons 에서는 h는 호스트 (host ) 바이트 순서를 의미
  • htons 에서의 n 은 네트워크 바이트 순서를 의미

  • htons : short 형 허스트 바이트를 네트워크 바이트 순서로 변환하라
  • ntohs : short 형 네트워크 바이트를 호스트 바이트 순서로 변환하라.
03-4 인터넷 주소의 초기화와 할당

+ 문자열 정보를 네트워크 바이트 순서의 정수로 변환하기
  • "211.214.107.99" 와 같은 문자열을 32비트 정수로 변환해 주는 함수
  • 또한 유효하지 않은 IP 주소에 대한 오류 검출 능력도 가지고 있다.
  • in_addr_t inet_addr(const char* string);
  • inet_aton : 기능상으로 동일하나 네트워크 바이트 순서로 반환한다.
  • if(!inet_aton(addr , &addr_inet.sin_addr))  char *addr = "127.233.124.79"; struct sockaddr_in addr_inet;
  • char * inet_ntoa(struct in_addr adr ) ;  // 정수 형태의 ip 주소를 문자열 형태의 ip 주소로 변환하여 반환.
  • 반환값이 문자열의 주소값이라는 의미는 이미 문자열이 메모리 공간에 저장되었다는 뜻.
  • 함수 내부적으로 메모리 공간을 할당해서 변환된 문자열 정보를 저장
  • 따라서 이함수 호출 후에는 가급적 반환된 문자열 정보를 다른 메모리 공간에 복사해 두는것이 좋다.  다시 한번 inet_ntoa 함수가 호출되면 저장된 문자열 정보가 지워질수 있기 때문이다.

+ 인터넷 주소의 초기화
  •  struct sockaddr_in addr;
  • char *server_ip = "211.217.168.13";
  • char *server_port = "9190";
  • memset(&addr, 0, sizeof(addr));
  • addr.sin_family = AF_INET;
  • addr.sin_addr_s_addr = inet_addr(server_ip);
  • addr.sin_port = htons(atoi(serv_port)); 

+ INADDR_ANY ( addr.sin_addr_s_addr = htonl( INADDR_ANY );
  • 컴퓨터의 IP 주소가 자동으로 할당됨.  
  • 컴퓨터 내의 두개 이상의 IP 를 할당 받아서 사용하는 경우(MULIT-HOMED COM  : 일반적으로 라우터 )  , 할당 받은 IP 중에서 어떤 주소를 통해서 데이터가 들어오더라도 POR 번호만 일치하면 수신 가능 
  • 서버의 경우 IP 주소의 초기화를 요구하는 의미는 하나의 컴퓨터에 둘이상의 IP 주소가 할당될수 있다는 것을 유추할수 있다.
  • 서버 소켓이라 할지라도 어떤 IP 주소로 들어오는 데이터를 수신할지 결정해야 한다.
+ 소켓에 인터넷 주소 할당하기
  • int bind(int sockfd, struct sockaddr * myaddr, socklen_t addr_len);
  • myaddr 구조체의 아이피, 포트 번호로 들어오는 데이터는 모두 내게 보내라!! 라는 의미

03-5 윈도우 기반 구현하기

+ 함수 htons, htonl 윈도우 기반 사용 예

+함수 inet_addr, inet_ntoa 의 윈도우 기반 사용 예

+WSAStringToAdress & WSAAdressToString
Posted by 뉴암스테르담
l