[LINUX] TINY webserver 만들기 (2) - 호스트와 서비스 변환

piopiop·2021년 1월 25일
0

Linux

목록 보기
3/6

리눅스는 getaddrinfo와 getnameinfo라고 하는 강력한 함수들을 제공하는데 이들은 이진 소켓 주소 구조체들과 호스트 주소, 포트번호 사이의 변환을 가능하게 해준다.

호스트와 서비스 변환

(1)getaddrinfo 함수

getaddrinfo함수는 호스트주소, 포트번호의 스트링 표시소켓 주소 구조체로 변환한다. 이 함수는 모든 프로토콜에 대해 동작한다.

소켓 주소의 구성요소인 호스트와 포트가 주어지면, getaddinfo는 각각이 호스트와 포트에 대응되는 소켓 주소 구조체를 가리키는 addrinfo 구조체의 연결리스트를 가리키는 result를 리턴한다.

int getaddrinfo(const char *host, const char *service, const struct addrinfo *hints, struct addrinfo **result);

	성공시 0 반환, 실패시 0이 아닌 에러코드 반환

host인자에는 도메인 이름 또는 숫자주소(ip주소) 둘 다 들어갈 수 있다. service인자는 서비스 이름(http, telnet 등) 또는 십진수 포트 번호가 들어간다. host나 service인자 둘 중 하나에는 NULL이 들어갈 수 있다.

struct addrinfo {
    int 		ai_flags; // hints로 쓸 때 사용
    int 		ai_family; 
    int 		ai_socktype;
    int 		ai_protocol;
    char 		*ai_canoname; 
    size_t 		ai_addrlen; // ai_addr의 크기
    struct sockaddr 	*ai_addr; // sockaddr 구조체의 포인터(소켓주소가 들어있음)
    struct addrinfo 	*ai_next; // 연결 리스트의 다음 원소를 가리키는 포인터

hints인자는 getaddrinfo가 반환하는 addrinfo 구조체들에 대한 요구사항이 있을 때 사용한다. hints인자 또한 addrinfo 구조체로 ai_family, ai_socktype, ai_protocol, ai_flags 필드만이 설정될 수 있으며 나머지 인자는 0 또는 NULL로 설정되어야 한다.
예를 들어 hints.ai_family = AF_INET;, hint.ai_socktype = SOCK_STREAM;이 설정되었다면 getaddrinfo의 결과로 반환된 연결리스트의 addrinfo 구조체들은 모두 AF_INET, SOCK_STREAM의 조건에 해당하는 ipv4의 TCP 소켓이다.

result인자는 조건에 맞는 addrinfo 구조체들의 연결리스트가 들어갈 주소값이다.

getaddrinfo의 가장 큰 장점 중 하나는 addrinfo의 필드들이 추가적인 조작 없이 소켓 인터페이스에서 함수들로 직접 전달될 수 있다는 것이다.
이전 포스트에서 설명했던 connet와 bind 함수에 addrinfo의 ai_family, ai_socktype, ai_protocol 인자는 직접 전달될 수 있다.

(2) getnameinfo함수

getnameinfo 함수는 getaddrinfo 함수의 역이다. 이 함수는 소켓 주소 구조체를 대응되는 호스트와 서비스 이름 스트링으로 변환한다.

int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *service, size_t servlen, int flags);
	
    성공시 0 반환, 실패시 0이 아닌 에러코드 반환

sa인자는 salen 바이트 크기의 소켓 주소 구조체가 들어간다. host는 hostlen 크기의 버퍼, service는 servlen 크기의 버퍼가 들어간다.
함수의 실행이 성공하면 소켓 주소 구조체 sa를 대응되는 호스트와 서비스 이름 스트링으로 변환하고, 이들을 host와 service 버퍼로 복사한다.
호스트 이름을 원하지 않거나 서비스 이름을 원치 않는다면 둘 중 하나는 NULL로 설정이 가능하다.
flags 인자는 비트 마스크로 기본 동작을 수정한다.
flags = NI_NUMERICHOST를 설정한다면 기본값으로 host를 도메인 이름으로 반환하는 것 대신 ip주소 스트링을 대신해서 반환한다.
NI_NUMERICSERV를 설정한다면 서비스 이름 대신 포트 번호를 반환한다.

profile
piopiop1178@gmail.com

0개의 댓글