addrinfo, sockaddr 구조체부터 변환 함수까지 한 번에 정리하기
앞선 포스트에서는 소켓 함수의 흐름을 정리했었는데요. 이번엔 그 함수들을 실제로 사용할 때 꼭 알아야 할 도구들인 sockaddr
, addrinfo
구조체와 getaddrinfo()
, inet_pton()
같은 핵심 함수들을 정리해보겠습니다. 구체적으로 실제 코드를 해석할 수 있는 안목을 기르는 데 초점을 맞췄습니다.
소켓 주소 구조체 제대로 이해하기
sockaddr (상위 타입 주소)
모든 주소 구조체의 공통 부모 역할을 하는 구조체입니다. 실제 주소는 sockaddr_in
처럼 구체적인 타입에서 정의하고, 소켓 함수에 넘길 땐 형 변환을 통해 사용하게 됩니다.
sockaddr_in (IPv4 주소용 구조체)
sin_family
: 주소 체계 (AF_INET)sin_port
: 포트 번호 (htons() 변환 필요)sin_addr
: IP 주소 (inet_pton() 필요)
주소 지정 시 바이트 순서 변환을 항상 해줘야 한다는 점을 잊지 말아야 합니다.
addrinfo: (getaddrinfo()와 짝꿍을 이루는 주소 구조체)
getaddrinfo()
함수와 함께 사용하는 구조체로, IP 주소, 포트 번호, 소켓 타입 등의 정보를 담고 있습니다. 통신에 필요한 '주소 안내서' 같은 역할을 하죠.
getaddrinfo(): 주소 해석의 핵심 함수
이 함수는 도메인명/포트명을 받아 주소 구조체 리스트를 반환해주는데요. struct addrinfo
로 원하는 힌트를 설정하고, 그 결과로 나오는 리스트를 순회하면서 소켓을 연결 시도하는 패턴이 가장 기본적입니다.
인자 정리
hostname
: "www.example.com" 또는 "127.0.0.1"servicename
: "http" 또는 포트 번호 문자열hints
: 어떤 형식의 주소가 필요한지 조건 설정result
: 연결 리스트의 헤드 포인터
기본 사용 패턴
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
getaddrinfo("example.com", "80", &hints, &res);
이후 res
를 순회하며 socket()과 connect() 시도 후, freeaddrinfo(res)를 통해 사용이 끝난 구조체를 반환합니다.
inet_pton(), inet_ntop(): IP ↔ 문자열 변환
inet_pton()
: 문자열을 네트워크 주소로 변환하는 함수inet_ntop()
: 네트워크 주소를 문자열로 변환하는 함수
사용 예시
char ipstr[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &ipv4->sin_addr, ipstr, sizeof ipstr);
printf("IP address: %s\n", ipstr);
이는 로깅이나 출력 결과를 표시하는 데 아주 유용합니다.
getnameinfo(): sockaddr → 문자열로 해석
getaddrinfo()
의 정확히 반대 역할을 수행합니다. sockaddr
을 넣으면, IP 주소
와 포트
를 문자열로 알려주게 되죠.
사용 예시
char host[NI_MAXHOST], service[NI_MAXSERV];
getnameinfo((struct sockaddr *)&addr, sizeof(addr),
host, sizeof(host), service, sizeof(service),
NI_NUMERICHOST | NI_NUMERICSERV);
"128.2.194.242", "8080" 이런 식으로 결과를 얻을 수 있습니다.
에러 처리와 리소스 정리
freeaddrinfo()
: 메모리 누수 방지close()
: 소켓 디스크립터 정리perror()
,strerror(errno)
: 에러 메시지 출력
CSAPP은 이런 처리를 깔끔하게 묶어주는 wrapper 함수를 csapp.c
에 정의해두었는데요. Socket()
, Connect()
를 같이 쓰면 깔끔하고 견고한 코드를 보다 쉽게 완성할 수 있습니다.
마치면서
이제 구조체도, 주소 변환 함수도, 에러 처리도 모두 정리해 보았는데요. 이제부터는 Tiny Web Server의 코드나 11.5절 구현 예제를 읽을 때도 '이게 어디서 나온 구조체고, 왜 이 함수를 사용하는지'가 한 눈에 들어올 것입니다.
그럼 다음 포스트에서 본격적으로 서버를 만들고, 다중 클라이언트 처리를 어떻게 구성할지에 대해 이어가보겠습니다. 감사합니다!
'크래프톤 정글 > 컴퓨터구조(CSAPP)' 카테고리의 다른 글
[CSAPP 11장 완전 정복] 11.5~11.6(Part 1) 웹 서버의 세계로 한 걸음, Tiny는 왜 필요한가? (0) | 2025.05.03 |
---|---|
CSAPP 11.5~11.6 rawdata 공유 (전체 학습 목표, 학습 정리 자료) (0) | 2025.05.03 |
[CSAPP 11장 완전 정복] 11.4(Part 1) 소켓 함수 흐름 완전정복, 클라이언트-서버 연결의 모든 것 (0) | 2025.05.02 |
[CSAPP 11장 완전 정복] 11.4 rawdata 공유 (전체 학습 목표, 학습 정리 자료) (0) | 2025.05.02 |
[CSAPP 11장 완전 정복] 11.3 IP, 포트, DNS, 바이트 순서까지, 실전 소켓 프로그래밍 개념 정리 (0) | 2025.05.01 |