본문 바로가기
Computer Science/TCP&IP 소켓 프로그래밍

3-1. 소켓 주소 구조체 다루기 (SOCKADDR, IN_ADDR, sockaddr_in,

by JI NY 2023. 11. 13.

3-1. 소켓 주소 구조체 다루기

  • 소켓 주소 구조체를 소개하고, 구조체를 초기화 하는 것을 익혀보자

01. 소켓 주소 구조체(socket address structures)

1) 소켓 주소 구조체란?

→ 소켓을 생성할 때 필요로 하는 주소 정보를 담고 있는 구조체.

  • 다양한 소켓 함수의 인자로 사용됨.
  • 프로토콜 체계에 따라 다양한 형태가 존재
    • TCP/IP ⇒ SOCKADDR_IN{}
  • 기본형은 SOCKADDR 구조체이고, ws2def.h 파일에 정의되어 있음

 

2-0) SOCKADDR 구조체 : 기본형

typedef struct sockaddr {
    u_short	 sa_family;
    char		 sa_data[14];
} SOCKADDR;
  • sa_family : 주소 체계를 나타내는 16bit 정수값.
    • TCP/IP를 쓰는 경우 AF_INET
  • sa_data[14] : 해당 주소 체계에서 사용할 주소 정보를 담는다. 바이트 배열이다.
    • TCP/IP를 쓰는 경우 IP주소 & 포트번호가 저장됨.

 

 

2-1) TCP/IP 소켓 address 구조체

  1. SOCKADDR_IN : IPv4 소켓 address 구조체
typedef struct sockaddr_in {
    short        	   	sin_family;	// AF_INET
    u_short         	sin_port;    	// 포트 번호 (우리가 넣어줘야할 값. u_short: 2byte)
    struct **in_addr**   	sin_addr;   	// IPv4 주소 (우리가 넣어저야할 겂 : 구조체)
    char            	sin_zero[8];	// 그냥 0으로 설정 (IPv6를 수용하기 위해 들어간 옵션임)
} SOCKADDR_IN;
  • sin_family : 주소 체계 (AF_INEF)
  • sin_port : 포트번호, 부호없는 16bit 정수값
  • sin_addr : IP주소 의미. IPv4의 경우 32bit in_addr 구조체 사
  • sin_zero : 그냥 0으로 두자. IPv6를 수용하기 위해 들어간 것

 

2. SOCKADDR_IN6 구조체 - IPv6 소켓 address 구조체

typedef struct sockaddr_in6 {
    short          		sin6_family;	// AF_INET6
    u_short         	sin6_port;    	// 포트 번호
    u_long            sin6_flowinfo; // 대부분 0으로 설정
    struct in6_addr   sin6_addr;   	// IPv6 주소
    u_long            sin6_scope_id;	// 대부분 0으로 설정
} SOCKADDR_IN;
  • sin6_family : 주소 체계 (AF_INEF6)
  • sin6_port : 포트번호, 부호없는 16bit 정수값
  • sin6_addr : IP주소 의미. IPv6의 경우 128bit in_addr6 구조체 사

 

 

3. 소켓 주소 구조체 크기비교

  • 소켓 address 구조체는 크기가 크기 때문에, 소켓 함수 인자로 전달할 때는 항상 주소 값을 사용해야한다.
  • 또한 SOCKADDR 포인터형으로 변환(type casting)해야한다.
  • 또한 사용할 프로토콜에 따라 소켓주소구조체의 크기가 달라지므로 sizeof 연산자를 사용해 얻은 크기 정보를 같이 전달해야함.

 

 

 

2-1-1) IP 주소를 저장하기 위한 구조체 : in_addr & in6_addr

  1. IN_ADDR 구조체 (IPv4)
    1. IPv4 IP 주소(address) 저장용
    typedef struct in_addr {
        union { // Union은 아래 목록 형식 중 아무거나 해도 된다는 것임
            struct { u_char s_b1, s_b2, s_b3, s_b4; } S_un_b; // 한 byte씩 끊어서도 가능
            struct { u_short s_w1, s_w2; } S_un_w; // 2byte씩 끊어도 가능
            u_long S_addr; // Long으로 한번에 해도 가능 (전체 사이즈는 32bit)
        } S_un;
    #define s_addr S_un.S_addr
    } IN_ADDR;
    
    • 0 : 0 : 0 : 0
    • ㅁㅁ : ㅁㅁ
    • ㅁㅁㅁㅁ
  2. IN6_ADDR 구조체 (IPv6)
    1. IPv6 주소 저장용 , 이 친구는 in_addr이랑 다르게 그냥 단순한 바이트다 word배열임
    typedef struct in6_addr {
        union {
            u_char Byte[16]; // 16개면 128 byte
            u_short Word[8];
        } u;
    } IN6_ADDR;

 

 

3) 소켓 주소 구조체 사용 예시

  • 소켓 address 구조체는 크기가 크기 때문에, 소켓 함수 인자로 전달할 때는 항상 주소 값을 사용해야한다.
  • 또한 SOCKADDR 포인터형으로 변환(type casting)해야한다.
  • 또한 사용할 프로토콜에 따라 소켓주 소구조체의 크기가 달라지므로 sizeof 연산자를 사용해 얻은 크기 정보를 같이 전달해야함.
  1. 응용 프로그램이 소켓주소구조체를 초기화하고 소켓 함수를 넘겨주는 경우
// 소켓 주소 구조체를 초기화한다.
SOCKADDR_IN addr;
...

SocketFunc(..., (SOCKADDR *)&addr, sizeof(addr), ...);

 

2. 소켓 함수가 소켓 주소 구조체를 입력으로 받아 내용을 채우면, 응용 프로그램이 이를 출력 등의 목적으로 사용하는 경우

SOCKADDR_IN addr;
SocketFunc(..., (SOCKADDR *)&addr, sizeof(addr), ...);

// 소켓 주소 구조체를 사용한다.
...

 


출처 및 참고자료

- TCP/IP 윈도우 소켓 프로그래밍 [한빛아카데미]

 

 

 

댓글