#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
struct in_addr
{
unsigned long int s_addr;
};
int inet_aton(const char *cp, struct in_addr *inp);
char *inet_ntoa(struct in_addr in);
in_addr_t inet_addr(const char *cp);
in_addr_t inet_network(const char *cp);
inet_aton()
IPv4의 Dotted-Decimal Notaion 아이피 주소를 네트워크 바이트 오더(big-endian) 바이너리 폼으로 변경하여 in_addr에 저장한다. 주소가 정상적인 것이라면 0이 아닌 값을 리턴하고, 그렇지 않다면 0을 리턴한다.
#include <arpa/inet.h>
#include <iostream>
int main()
{
in_addr in;
// if(0 == inet_aton("256.256.256.256", &in)) 범위를 벗어 나는 ip
// if(0 == inet_aton("kukuta.tistory.com", &in)) 숫자로 된 ip 주소가 아님
if(0 == inet_aton("192.168.0.1", &in)) // 정상적인 ip 주소
{
std::cerr << "inet_aton error" << std::endl;
exit(1);
}
std::cout << in.s_addr << std::endl;
}
※ 인텔계열의 CPU의 host byte order는 network byte order와 반대라고 한다. 코딩할때 꼭 유의 하도록 한다. byte order에 관련 추가 설명은 [여기]를 참고 하도록 하자.
inet_ntoa()
네트워크 바이트 오더(big-endian)의 바이너리 주소를 IPv4의 Dotted-Decimal Notation 아이피 주소로 변경한다. 단, 리턴되는 버퍼가 내부에서 static으로 잡혀 있으므로 threadsafe하지 않다. 만일 쓰레드에 대한 고려를 해야 한다면 _r이 붙은 함수를 사용하여야 한다.
※ 원래는 reenterent에 안전하지 않은 것이지만, 어차피 reenterent에 안전하지 않으면 threadsafe하지 않으므로 그냥 threadsafe하지 않다고 했다.
#include <arpa/inet.h>
#include <iostream>
int main()
{
in_addr in;
// 192.168.0.1을 네트워크 바이트 오더 바이너리 폼으로 변환
if(0 == inet_aton("192.168.0.1", &in))
{
std::cerr << "inet_aton error" << std::endl;
exit(1);
}
// 네트워크 바이트 오더 바이너리 폼을 점으로 구분된 아이피 주소로 변환
char* addr = inet_ntoa(in);
std::cout << addr << std::endl;
}
inet_addr()
IP address를 네트워크 바이트 순서(Network-byte order)의 바이너리 데이터를 리턴한다. 만일 입력값이 부적절 하다면 INADDR_NONE(대체로 -1)을 리턴한다.
/**
inet_addr() 함수는 위에 나온 inet_aton() 함수 보다 좀 덜떨어진(?) 함수로써 255.255.255.255가 -1을 리턴하기 때문에 코딩을 하면서 오류의 소지가 있을 수 있다. 그리고 inet_aton() 함수는 에러 발생시 어떤 에러가 발생했는지 보다 자세히 리턴 한다. 하지만 inet_addr() 함수가 쓰기 편하다.
*/
inet_network()
위의 inet_addr과 비슷한 역할을 하지만 호스트 바이트 순서(Host-byte order)의 바이너리 데이터를 리턴한다.