소켓을 생성한 다음에 서버의 경우 bind 함수를 사용해서 소켓에 주소를 부여할 수 있고, 클라이언트의 경우 connect함수 내부에서 자동으로 주소를 할당이 된다.

소켓의 주소라는 것이 어떻게 생겼는지 소켓에 그 주소를 어떻게 바인딩하는지가 목표

IPv4 인터넷 주소의 체계

처음 8비트는 네트워크를 구분하고 나머지 24비트는 네트워크 안의 호스트들을 구분하는 데 사용된다.

일반적으로 클래스C를 사용.

3바이트로 인하대학교 네트워크를 발견하고, 네트워크 내부에서 사용하는 호스트들은 나머지 1바이트로 구분

클래스 A의 첫 번째 비트는 항상 0으로 시작
클래스 B의 첫 두 비트는 항상 10으로 시작
클래스 C의 첫 세 비트는 항상 110으로 시작
클래스 C에서 마지막 1바이트인 IP로 PC 시스템 하나를 구분하고 Port번호로 하나의 시스템에서 동작하고 있는 수많은 어플리케이션들을 구분한다. 그러나 어플리케이션과 port 하나를 구분하지 않는다. 소켓하나당 port가 하나를 구분하는 것

IP +Port 번호로 소켓하나를 구분하는 것

PORT번호는 16bit로, 따라서 그 값은 표현 0~(

-1)

0~1023은 잘 알려진 port(Well-known PORT)라 해서 이미 용도가 결정되어 있다.

IP와 PORT번호를 어떤 자료구조로 할당하는가?

IPv4 기반의 주소표현을 위한 구조체로 sockaddr_in이 있다. 이 변수안에 IP주소와 PORT번호 정보를 담는다.

1
2
3
4
5
6
struct sockaddr_in {
    sa_family_t        sin_family;
    uint16_t        sin_port;
    struct in_addr    sin_addr;
    char            sin_zero[8];
};
cs

이 안에는

- 주소체계를 나타내는 sin_family,

- PORT번호를 나타내는 sin_port(2byte),

- 32비트 IP주소를 나타내는 sin_addr(4byte),

- sin_zero[8](8byte) - 0으로 채움 (사용하지 않음)

까지4가지 변수가 있다.

여기서 sin_addr는 struct in_addr라는 구조체 타입인데, 이 변수 안에는 in_addr_t 라는 자료형을 갖는 s_addr 변수가 있다.

여기에 32bit IPv4 인터넷 주소 정보를 담는다.

이 자료형은 uint32_t로 정의되어 있는 데 왜 구분되어 사용되는 것일까?

이름을 보고 의미를 파악하게 하기위해, 해당 속성마다 이름을 구분하여 시스템 확장성을 위함이다. (즉, 직관성, 확장성)

sin_family는 PF(Protocol Family)인지 AF(Address Family)를 구분 - IPv4, IPv6 구분

sockaddr_in 구조체 변수는 bind 함수의 인자로 전달되는데 매개변수 형이 sockaddr으로 형변환을 해야만 한다.

sockaddr이 먼저 생겨나거 그 세부사항을 나눠서 표현하기 위해 sockaddr_in 구조체 타입을 생성한 것이라 생각하면 편한다.

sockaddr 타입 안에는 두 개의 변수가 있다. sin_family 변수는 sockaddr_in과 같다. 다른 하나는 sa_data[14]인데 sockaddr_in에서 sin_port, sin_addr, sin_zero[0] 총 14 byte의 정보가 sa_data에 포함된다. 따라서 IPv4에 맞춰서 sa_data의 14byte를 구분해놓은 것이 sockaddr_in 구조체 타입 변수이다.

따라서 우리는 sockaddr_in으로 정의했기 때문에 bind 로 넘길 때는 sockaddr로 강제 형변환을 하여 넘긴다.

'CS & IT실무' 카테고리의 다른 글

IO 멀티플렉싱  (0) 2018.11.13
Half-Close - shutdown()  (0) 2018.10.05
네트워크 바이트 순서와 인터넷 주소 변환  (0) 2018.10.04