소켓 주소 구조체(docket address structures)란?
기본적으로 사용되는 소켓 주소 구조체는 SOCKADDR
구조체로, ws2def.h
파일(winsock2.h
파일에 포함)에 아래 처럼 정의 되어 있다.
typedef struct sockaddr
{
u_short sa_family; // u_short: unsigned short
char sa_data[14];
} SOCKADDR;
AF_INET
또는 AF_INET6
응용 프로그램이 사용할 프로토콜의 종류에 맞는 별도의 소켓 구조체를 사용해야 한다.
예를 들어 TCP/IP에서는 SOCKADDR_IN
또는 SOCKADDR_IN6
를 사용하고, IrDA(Infrared Data Association; 적외선을 통한 무선 통신 프로토콜)에서는 SOCKADDR_IRDA
를 사용한다.
주로 사용되는 TCP/IP 프로토콜을 위한 소켓 주소 구조체는 IP 버전에 따라 두 종류 이며, 각각 ws2def.h
(winsock2.h
파일에 포함)과 ws2ipdef.h
(ws2tcpip.h
파일에 포함)파일에 다음과 같이 정의되어 있다.
/* IPv4 소켓 주소 구조체 */
typedef struct sockaddr_in
{
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[0]; // 대부분 0으로 설정
} SOCKADDR_IN;
/* IPv6 소켓 주소 구조체 */
typedef struct sockaddr_in6
{
short sin6_family;
u_short sin6_port;
u_long sin6_flowinfo; // 대부분 0으로 설정
struct in6_addr sin6_addr;
u_long sin6_scope_id; // 대부분 0으로 설정
} SOCKADDR_IN6;
AF_INET
, AF_INET6
값을 사용한다.in_addr
구조체와 128비트 in6_addr
구조체를 사용한다.IP 주소를 저장하기 위한 in_addr
구조체와 in6_addr
구조체는 각각 inaddr.h
(winsock2.h
파일에 포함)과 in6addr.h
(ws2tcpip.h
파일에 포함)에 아래와 같이 정의 되어 있다.
typedef struct in_addr
{
union
{
struct { u_char s_b1, s_b2, s_b3, s_b4; } S_un_b;
struct { u_short s_w1, s_w2; } S_un_w;
u_long S_addr;
} S_un;
#define s_addr S_un.S_addr
} IN_ADDR;
typedef struct in6_addr
{
union
{
u_char Byte[16];
u_short Word[8];
} u;
} IN6_ADDR;
IPv4 주소를 담는 in_addr
구조체는 동일 메모리 영역을 각각 8비트(S_un_b
), 16비트(S_un_w
), 32비트(S_addr
) 단위로 접근할 수 있게 만든 공용체(S_un
)임을 알 수 있다. 응용 프로그램에서는 대개 32비트 단위로 접근하므로 S_un.S_addr
필들르 사용하여, 매크로를 통해 재정의된 s_addr
을 사용하면 편하다.
in_addr
구조체와 달리 IPv6 주소를 담는 in6_addr
구조체는 단순한 파이트 또는 워드 배열로 정의되어 있다.
소켓 주소 구조체의 크기가 아래 표에 정의 되어 있다. 위에서 살펴본 SOCKADDR
, SOCKADDR_IN
, SOCKADD_IN6
뿐만 아니라 IrDA 프로토콜에서 사용하는 SOCKADDR_IRDA
와 블루투스 프로토콜에서 사용하는 SOCKADDR_BTH
구조체도 같이 표시했다.
구조체 이름 | 전체 크기 (바이트 단위) |
---|---|
SOCKADDR | 16 |
SOCKADDR_IN | 16 |
SOCKADDR_IN6 | 28 |
SOCKADDR_IRDA | 32 |
SOCKADDR_BTH | 30 |
SocketFunc()
은 임의의 소켓 함수)// 소켓 주소 구조테를 초기화
SOCKADDR_IN addr;
...
SocketFunc(..., (SOCKADDR *) &addr, sizeof(addr), ...);
SocketFunc()
은 임의의 소켓 함수)SOCKADDR_IN addr;
SocketFunc(..., (SOCKADDR *) &addr, sizeof(addr), ...);
// 소켓 구조체를 사용한다.
...
주의 사항
SOCKADDR
포인터 형으로 변환(type casting)해야 한다.sizeof
연산자를 사용해 얻은 크기 정보를 같이 전달해야 한다.참고 자료
김성우 저, "TCP/IP 윈도우 소켓 프로그래밍", 한빛아카데미, 2018