IP주소 및 포트 정보관련 시스템 함수
System Program/socket 2014. 3. 4. 14:301. getaddrinfo() 함수
호스트와 서비스명에 해당하는 IP 주소와 포트로 찾아 변환한다.
기존 gethostbyname()과 getserverbyname() 함수를 대체하였다.
#include <netdb.h>
int getaddrinfo(const char *host, const char *service,
const struct addrinfo *hints, struct addrinfo **result);
성공하면 '0'을 리턴하고, 에러가 발생하면 '0'이 아닌 값을 리턴
getaddrinfo()함수는 host, service, hist 값을 입력으로 result로부터 정보를 추출하는 구조이다.
addrinfo 구조체는 아래와 같다.
int ai_flags; /* 입력 플래그 (AI_* 상수) */
int ai_family; /* 주소 패밀리 : AF_INET, AF_INET6 */
int ai_socktype; /* 종류 : SOCK_STREAM, SOCK_DGRAM */
int ai_protocol; /* 소켓 프로토콜 */
size_t ai_addrlen; /* ai_addr 이 가르키는 구조체 크기 */
char * ai_canonname; /* 공식 호스트 명 */
struct sockaddr *ai_addr; /* 소켓 주소 구조체를 가르키는 포인터 */
struct addrinfo *ai_next; /* 링크드 리스트에서 다음 구조체 */
};
1.1. hints 인자에 대한 고찰
hints 인자를 통해서 getaddrinfo() 함수에서 리턴하는 주소 구조체의 정보를 선택적으로 취할 수 있다.
ai_flags, ai_family, ai_socktype, ai_protocol만 설정할 수 있다.
ai_family에는 AF_INET, AF_INET6, AF_UNSPEC 설정 가능. 마지막 값은 모든 종류를 리턴하도록 강제한다.
ai_socktype에는 SOCK_DGRAM, SOCK_STREAM, 0이 가능, 0이면 모든 값을 리턴
ai_protocol에는 대충 '0'을 설정한다.
ai_flags는 getaddrinfo()함수의 수행 방식을 변경하는 비트 마스크다. '0'혹은 아래 값과 OR연산한다.
flags |
설명 |
AI_ADDRCONFIG |
로컬 시스템에 IPv4, IPv6 중에 하나가 있으면 리턴 |
AI_ALL |
AI_V4MAPPED 참조 |
AI_CANNAME |
host가 NULL이 아닌 경우, NULL로 종료하는 공식 호스트명 포인트 리턴 |
AI_NUMERICHOST |
host를 숫자로 이뤄진 주소 문자열로 해석하도록 강제 |
AI_NUMERICSERC |
service를 숫자 포트 번호로 해석하도록 강제 |
AI_PASSIVE |
수동 접속에 적합한 소켓 구조체 리턴 |
AI_V4MAPPED |
IPv6 주소를 발견하지 못하면 IPv4로 매핑된 주소를 리턴 |
2. addrinfo 리스트 해제 : freeaddrinfo()
getaddrinfo() 함수는 result가 가르키는 모든 구조체 메모리를 동적으로 할당한다.
getaddrinfo() 함수를 호출한 곳에서 해당 구조체를 사용하고 메모리 해제를 책임져야 한다.
#include <netdb.h>
void freeaddrinfo(struct addrinfo *result);
3. 에러 진단 : gai_strerror()
에러가 발생한 경우 아래 값 중에 하나를 에러코드로 리턴한다.
const char *gai_strerror(int errcode);
아래 에러 상수에 해당하는 문자열을 리턴
에러 상수 |
설명 |
EAI_ADDRFAMILY |
hints.ai_family에 해당하는 호스트 주소가 없다 |
EAI_AGAIN |
이름 해석 일시 오류(나중에 다시 시도) |
EAI_BADFLAGS |
hints.ai_flags에 잘못된 플레그 설정 |
EAI_FAIL |
이름 서버에 접속하면서 회복할 수 없는 실패가 생성 |
EAI_FAMILY |
hints.family에 설정한 주소 패밀리를 지원할 수 없음. |
EAI_MEMORY |
메모리 할당 에러 |
EAI_NODATA |
host에 해당하는 주소를 찾을 수 없음 |
EAI_NONAME |
host나 service를 알수 없음. |
EAI_OVERFLOW |
인자 버퍼 오버플로우 |
EAI_SERVICE |
hints.ai_socktype에 알맞은 service를 지원하지 않음. |
EAI_SOCKTYPE |
hints.ai_socktype을 지원하지 않음. |
EAI_SYSTEM |
errno로 시스템 에러를 리턴 |
4. getnameinfo() 함수
getaddrinfo() 함수와 정반대의 동작을 수행한다.
#include <netdb.h>
int getnameinfo(const struct sockaddr *addr, socklen_t addrlen,
char *host, size_t hostlen, char *service, size_t servlen, int flags);
성공하면 '0'을 리턴, 에러가 발생하면 '0'이 아닌 값을 리턴
sockaddr 구조체를 통해 address 정보를 주면 host와 service에 대한 정보를 얻을 수 있다.
flags에 대한 자세한 내용은 아래 표를 참조
flags |
설명 |
NI_DGRAM |
데이터그램 소켓에 대한 정보를 리턴하도록 강제한다. |
NI_NAMEREQD |
호스트명을 찾을 수 없으면 숫자를 기본적으로 리턴하나 해당 플레그로 에러 리턴 |
NI_NOFQDN |
기본적으로 FQDN을 리턴, 호스트가 로컬일 경우만 FQDN의 첫 부분만 리턴 |
NI_NUMERICHOST |
DNS 대신 host에 숫자 형식의 문자열을 리턴하도록 강제 |
NI_NUMERICSERV |
십진수 포트 번호를 리턴하도록 강제, /etc/services에 검색하지 않음. |
5. 구형 유사 함수
5.1. IP 주소를 얻어오는 함수
extern int h_errno;
struct hostent *gethostbyname(const char *name);
struct hostent *gethostbyaddr(const char *addr, socklen_t len, int type);
성공하면 hostent 구조체의 포인터를 리턴, 에러가 발생하면 NULL을 리턴
5.2. 포트 정보를 얻어오는 함수
/etc/services 파일에서 레코드를 가져오는 함수들이다.
struct servent *getservbyname(const char *name, const char *proto);
struct servent *getservbyport(int port, const char *proto);
성공하면 servent구조체의 포인터를 리턴, 에러가 발생하면 NULL을 리턴
'System Program > socket' 카테고리의 다른 글
연결형 에코 서버 예제 (0) | 2014.03.06 |
---|---|
소켓옵션 (0) | 2014.03.05 |
IP주소 및 포트 관리 (0) | 2014.03.04 |
주소 구조체 (0) | 2014.03.04 |
호스트,네트워크간 변환 함수 정리 (0) | 2014.03.04 |