(1) Internet Address

○ IP(Internet Address) 
: 인터넷에 존재하는 호스트들을 구분하기 위한 32비트 주소 체계
  점이 찍힌 십진수 표현 방식(Dotted-decimal Notation) : 211.217.10.9

○ 클래스

- Class A : 0.0.0.0 ~ 127.255.255.255, 1바이트는 네트워크 ID, 3바이트는 호스트 ID
- Class B : 128.0.0.0 ~ 191.255.255.255, 2바이트는 네트워크 ID, 2바이트는 호스트 ID
- Class C : 192.0.0.0 ~ 223.255.255.255, 3바이트는 네트워크 ID, 1바이트는 호스트 ID
- Class D : 멀티캐스트 주소. 224.0.0.0 ~ 239.255.255.255
- Class E : 예약됨. 240.0.0.0 ~ 255.255.255.255

IP 주소 : 네트워크 주소(네트워크를 구분지음) + 호스트 주소(호스트를 구분지음)
subnet mask에 따라서 네트워크 주소(ID)와 호스트 주소(ID)로 나누어진다.

※ 라우터는 네트워크 ID(주소)만 참조한다.
※ 루프백 주소 : 127.x.x.x, 네트워크 상으로 패킷을 전송하지 않고 자기자신에게 돌려준다.


(2) Port란 무엇인가?

Port
:
호스트 내에서 실행되고 있는 프로세스를 구분 짓기 위한 16비트의 논리적인 값. (소켓에 할당)

- 논리적인 값 : 소프트웨어 적으로 구현. 
- Well-known ports : 0~1023


(3) 주소 정보의 표현
:
IPV4의 주소 체계를 나타내는 구조체

※ 하나의 프로토콜 내에 2개 이상 프로토콜이 있을 것을 대비해서 만든 구조체. ()는 윈도우즈용.
※ 모든 데이터는 네트워크 바이트 순서로 저장해야 한다.

struct sockaddr_in
{
    sa_family_t(short) sin_family; // 주소 체계(address_family) - AF_INET
    uint16_t(unsigned short) sin_port; // 16비트 TCP 혹은 UDP 포트
    struct in_addr sin_addr; // 32비트 IPv4 주소
    char sin_zero[8]; // 사용되지 않음. padding 용도
};

struct in_addr
{
   
uint32_t(unsigned long) s_addr; // 32비트 IPv4 인터넷 주소
};


(4) 네트워크 바이트 순서

0x12345678을 Big-Endian으로는 메모리 순서대로 0번지 0x12, 1번지 0x34, 2번지 0x56, 3번지 0x78
0x12345678을 Little-Endian으로는 메모리 순서대로 0번지 0x78, 1번지 0x56, 2번지 0x34, 3번지 0x12 형태로 저장.


○ 호스트 바이트 순서 
:
어떤 시스템(motorola, sun사 기계)은 Big-Endian, 어떤 시스템(intel사)은 Little-Endian을 사용하므로 일정하지 않다.
※ 데이터 표현 방식이 다르므로 다른 플랫폼끼리 문제가 발생한다.

○ 네트워크 바이트 순서
:
Big-Endian 방식을 적용하기로 하였다.

○  바이트 순서 변환 함수
어느 시스템에서 돌아갈 지 모르기 때문에 반드시 사용해야 한다.

unsigned short htons(unsigned short); // 호스트 -> 네트워크 short
unsigned short ntohs(unsigned short); // 네트워크 -> 호스트 short
unsigned long htonl(unsigned long); // 호스트 -> 네트워크 long
unsigned long ntohl(unsigned long); // 네트워크 -> 호스트 long

- 'h' : host byte order
- 'n' : network byte order
- 's' : short(16비트)
- 'l' : long(32비트)


(5) 인터넷 주소 조작하기

○ 점이 찍힌 십진수 방식(Dotted-Decimal Notation)을 Big-Endian 32비트 정수형 데이터로 바꿔주는 함수 (네트워크)

#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

unsigned long inet_addr(const char *string);
리턴 : 성공시 32비트 big-endian값, 실패시 INADDR_NONE

#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int inet_aton(const char* string, struct in_addr *addr);
리턴 : 성공시 true, 실패시 false
※ 바로 struct in_addr에 값을 제공할 수 있다.


○ Big-Endian 32비트 정수형 데이터를 점이 찍힌 십진수 방식로 바꿔주는 함수(네트워크)

#include<sys/socket.h>

#include<netinet/in.h>

#include<arpa/inet.h>

char* inet_ntoa(struct in_addr addr);

※ 따로 inet_ntoa 내부적으로 static 배열을 통해 주소에 대한 문자열이 존재한다.


(6) 인터넷 주소 초기화


struct sockaddr_in addr;

char *serv_ip = "...";

char *serv_port = "...";

memset(&addr, 0, sizeof(addr_len)); // 주소에 해당하는 구조체 값을 0으로 초기화. 좋은 습관.

addr.sin_family = AF_INET;

addr.sin_addr.s_addr = inet_addr(serv_ip);

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


INADDR_ANY?

addr.sin_addr.s_addr = htons(INADDR_ANY);

// 서버의 IP가 뭐더라? 답은 INADDR_ANY : 내 시스템의 IP 주소를 찾아 알아서 할당.


(7) 주소 정보 할당하기


리눅스


#include<sys/types.h>

#include<sys/socket.h>

int bind(int sockfd, struct sockaddr *myaddr, int addrlen);



※ 출처 : http://blog.daum.net/sdr1982/7027376

by 민트앤라떼 2011. 4. 13. 15:08