티스토리 뷰

IT/Network

[네트워크] sockaddr_in* 타입에서 sockaddr* 타입으로 강제 형변환이 가능한 이유

주인장 진빼이

TCP 및 UDP 프로토콜 소켓을 이용한 통신 코드를 짤 때 connect, bind 함수를 호출할 때가 있다.

이때 해당 함수들을 호출하기 위해 필요한  매개변수는 분명 sockaddr* 타입을 요구하고 있지만

코드를 보면 sockaddr_in* 타입의 변수를 sockaddr* 타입으로 강제 형변환하여 전달하고 있다.

 

강제 형변환이 가능한 이유는 sockaddr 구조체와 sockaddr_in 구조체의 메모리 블럭과 멤버변수의 크기 모두 동일하다.

만약 멤버변수 타입이나 차지하는 크기가 조금이라도 틀렸다면 강제 형변환 후 메모리 블럭을 맞춰줘야하는 작업을 진행할 필요가 있다.

 

말로는 이해하기 어려울 수 있으니 그림으로 이해하자

아래 그림에서 sockaddr_in 구조체의 멤버변수들이 차지하고 있는 메모리 블럭 및 메모리 데이터를 볼 수 있다.

sockaddr, sockaddr_in의 메모리 블럭 및 메모리 데이터

그림을 보면 알듯이 두 구조체가 차지하고 있는 메모리 블럭과 메모리 데이터에 들어갈 위치는 동일하다.

 

 

" sockaddr_in* 대신에 sockaddr* 타입을 사용하겠습니다 "

어느 타입을 쓰던 상관은 없지만 sockaddr_in 구조체는 주소 정보, 포트 정보가 나뉘어져 있기 때문에 마치 사용자에게 편의성을 제공해주는 것 같다. sockaddr 구조체는 주소 정보와 정보가 담겨져야할 큰 배열로 구성되어 있어 불편하게 느껴진다.

 

sockaddr 타입을 이용해보고 싶다면 다음 코드를 사용하자

sockaddr 구조체 변수를 사용하게 되면 포트 메모리 데이터를 따로 복사해줘야 한다.

포트의 최대 크기는 2byte(same as short type size) 타입과 같다 (0~65535)

sockaddr addr = { 0, };
addr.sa_family = AF_INET;
USHORT port = htons(9000);
memcpy_s(&addr.sa_data, 2, &port, 2);
inet_pton(AF_INET, "127.0.0.1", &addr.sa_data[2]);

 

 

" 두 구조체의 멤버변수가 차지하고 있는 크기 및 구조는 동일하기 때문에 강제 형변환을 해도 함수에게 넘겨주는 주소에서 데이터를 역참조(*)하여 접근해도 아무 문제가 없는 것이다. "

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함