01.JAVA/Java2008. 11. 12. 17:24
반응형

InetAddress 클래스는 자바 플랫폼이 처음 출시된 이래로 줄곧 사용되어 왔으며, 이 클래스의 역할은 인터넷 프로토콜(IP) 주소를 통해 호스트의 ID를 알려주는 것이다. 다시 말해서, 가령 yahoo.com 같은 이름을 입력하면 InetAddress 클래스의 도움으로 그 IP 주소를 알아낼 수 있다.

InetAddress 클래스 디자인은 다소 기묘해 보일 수도 있다. 클래스에는 static 선언만 있고 public 생성자가 없으며, 인스턴스는 불변, 즉 일단 클래스의 인스턴스를 가지면 변경할 수 없다. 하지만 그 디자인은 자바 보안의 목적을 위한 것으로서 사용자는 검색 간의 결과를 변경할 수 없다.

다음은 InetAddress 클래스의 사용 예제이다. 아래의 프로그램 Lookup은 명령어 라인에서 전달하는 아규먼트의 이름과 IP 주소를 알려준다.

   import java.net.*;

   public class Lookup {

     public static void main(String args[]) {
       for (String name: args) {
         try {
           InetAddress address = InetAddress.getByName(name);
           System.out.println("Name: " + address.getHostName());
           System.out.println("Addr: " + address.getHostAddress());
         } catch (UnknownHostException e) {
           System.err.println("Unable to lookup " + name);
         }
       }
     }
   }

이 프로그램에서 getByName() 메소드는 Microsoft Windows와 Unix의 nslookup 명령어와 같은 역할을 한다. 명령어 라인 아규먼트에 지정된 이름을 가져온 다음, 시스템에 지정된 네임 서버에서 룩업을 수행한다. 룩업을 수행할 때는 일반적으로 도메인 네임 시스템(DNS)을 이용한다. 룩업 작업은 yahoo.com 같은 이름이나 66.94.234.13 같은 IP 주소를 대상으로 이루어지는데, yahoo.com을 입력하면 66.94.234.13을 얻게 되고, 66.94.234.13을 입력하면 Yahoo의 호스트 팜(farm) 이름 목록을 얻게 된다. 이 경우 호스트의 퍼블릭 이름은 w2.rc.vip.scd.yahoo.com이다.

   > java Lookup sun.com yahoo.com 66.94.234.13

     Name: sun.com
     Addr: 209.249.116.195
     Name: yahoo.com
     Addr: 216.109.112.135
     Name: w2.rc.vip.scd.yahoo.com
     Addr: 66.94.234.13
	 

일부 호스트 이름은 복수의 IP 주소로 변환된다. InetAddressgetByName() 메소드를 이용해서 하나의 이름을 룩업하는 대신 getAllByName() 메소드를 이용하여 일련의 InetAddress 오브젝트를 얻어낼 수 있다.

아울러, InetAddress 클래스는 역순 이름 해석을 지원한다. 이는 특정 호스트에 대해 IP 주소를 룩업한 다음 그 IP 주소를 이용하여 호스트 이름을 룩업할 수 있음을 의미한다. 두 가지가 일치하지 않더라도 이것이 반드시 잘못되었다고 볼 수는 없겠지만, 만약 이 두 가지가 일치해야 하고 여러분이 그 사실을 알고 있는 상태라면 불일치 현상은 스푸핑 공격의 징후로 간주될 수 있다.

아래의 LookupAll 프로그램은 getAllByName() 메소드를 이용하여 호스트에 대한 모든 주소를 룩업한다. 그런 다음 getCanonicalHostName() 메소드를 이용하여 호스트에 대해 완전한 자격을 갖춘 도메인 이름을 룩업한다.

   import java.net.*;

   public class LookupAll {
     public static void main(String args[]) {
       for (String name: args) {
         try {
           InetAddress address[] = 
               InetAddress.getAllByName(name);
           for (InetAddress each: address) {
             System.out.println("Name: " + each.getHostName());
             System.out.println("Addr: " + 
                 each.getHostAddress());
             System.out.println("Canonical: " + 
                 each.getCanonicalHostName());
           }
           System.out.println("----");
         } catch (UnknownHostException e) {
           System.err.println("Unable to lookup " + name);
         }
       }
     }
   }

복수의 주소를 가지는 호스트의 하나로 google.com을 들 수 있는데, 다음 예제에는 google.com과 yahoo.com이 아규먼트로 포함되어 있다. 예제는 어떻게 yahoo.com에 대한 IP 주소의 역 룩업이 다른 호스트 이름으로 해석되는지를 잘 보여주고 있다.

   >> java LookupAll yahoo.com google.com

      Name: yahoo.com
      Addr: 216.109.112.135
      Canonical: w2.rc.vip.dcn.yahoo.com
      Name: yahoo.com
      Addr: 66.94.234.13
      Canonical: w2.rc.vip.scd.yahoo.com
      ----
      Name: google.com
      Addr: 216.239.39.99
      Canonical: 216.239.39.99
      Name: google.com
      Addr: 216.239.57.99
      Canonical: 216.239.57.99
      Name: google.com
      Addr: 216.239.37.99
      Canonical: 216.239.37.99
      ----

J2SE 플랫폼의 1.4 버전에는 getCanonicalHostName() 메소드가 추가되었다.

J2SE 5.0에서는 InetAddress를 이용하여 호스트의 도달 능력(reachability)을 확인할 수도 있다. 다시 말해서 호스트가 ‘살아있는지(즉, 활성화되어있는지)’의 여부를 결정할 수 있는 것이다. 이 테스트는 일반적으로 명령어 라인에서 ‘ping’ 명령어나 간단한 TCP ECHO 요청을 통해 수행된다. 그러나, 가령 2005년 9월 13일자 테크팁 Runtime.exe에서 ProcessBuilder까지 에서 설명했던 ProcessBuilder 클래스를 이용하여 굳이 명령어 라인 프롬프트를 열어야 할 필요가 있을까라는 질문을 던져본다. 그 대신 우리는 InetAddress에서 isReachable() 메소드를 이용하기만 하면 된다.

isReachable() 메소드에는 다음 두 가지 형태가 있다:

  • public boolean isReachable(int timeout) throws IOException
  • public boolean isReachable(NetworkInterface netif, int ttl, int timeout) throws IOException

대부분의 경우에는 첫 번째 버전의 isReachable로도 충분하다. 이 포맷에서는 단순히 검사(check)를 위한 타임아웃을 제공하는데, 타임아웃은 대상 호스트가 살아있는지 알아보기 위해 기다려야 하는 밀리초의 수를 나타낸다. 호스트가 죽어있으면 메소드는 ‘false’를 반환하고 핑 서비스는 사용 불능 상태로 되거나 요청은 방화벽에서 차단된다. 도달 가능한 호스트를 찾을 경우에는 메소드는 ‘true’를 반환하고, 네트워크 오류가 발행할 경우에는 메소드는 IOException을 전달한다

두 번째 버전의 isReachable은 테스트에 어떤 NetworkInterface를 이용할지 확인할 수 있게 해준다. 또한 특정 호스트에 도달하기 위해 시도하는 최대 호프(hop) 수를 지정할 수도 있다. 하나의 네트워크 인터페이스만을 가지고 있지만 호프 수를 지정하고자 한다면 임의의 인터페이스에 대해 null을 전달하면 된다. 첫 번째 버전의 isReachable과 마찬가지로, 타임아웃 값도 지정한다. 이 버전의 isReachable에서 가능한 반환 값은 원(1) 아규먼트 버전의 경우와 동일하다.

다음 프로그램 LookupReach는 이전의 단일 이름 룩업에 도달 가능 검사(check)를 추가한다.

   import java.io.*;
   import java.net.*;

   public class LookupReach {
     public static void main(String args[]) {
       for (String name: args) {
         try {
           InetAddress address = InetAddress.getByName(name);
           System.out.println("Name: " + address.getHostName());
           System.out.println("Addr: " + 
               address.getHostAddress());
           System.out.println("Reach: " + 
               address.isReachable(3000));
         } catch (UnknownHostException e) {
           System.err.println("Unable to lookup " + name);
         } catch (IOException e) {
           System.err.println("Unable to reach " + name);
         }
       }
     }
   }

yahoo.com, sun.com, goole.com 등을 아규먼트로 하여 LookupReach를 실행해 본다. 프로그램이 ‘false’를 반환하는 것을 보게 될 것이다. 거대 웹 기업들은 대부분 자사의 인터넷 사이트에서 이 서비스를 사용 불능으로 하거나 요청을 차단하고 있다. 다시 web.mit.edu 같은 대학교 사이트에 대한 아규먼트로 프로그램을 실행해 본다. 대부분의 대학교 사이트는 요청을 허용한다.

   > java LookupReach yahoo.com sun.com google.com web.mit.edu
   
     Name: yahoo.com
     Addr: 216.109.112.135
     Reach: false
     Name: sun.com
     Addr: 209.249.116.195
     Reach: false
     Name: google.com
     Addr: 216.239.37.99
     Reach: false
     Name: web.mit.edu
     Addr: 18.7.22.69
     Reach: true

InetAddress 클래스를 이용할 때는 일반적으로 사용되는 a.b.c.d. 형태로 된 IPv4 이름을 지정할 수 있다는 것을 염두에 두어야 한다. 또한 더 최근의 x:x:x:x:x:x:x:x형태로 이루어진 IPv6 이름도 지정할 수 있는데, 여기서 ‘x’는 8개의 16비트 주소에 대한 헥스(hex) 값이다. IPv6 아키텍처에 관한 자세한 내용은 RFC 2373을 참조하도록 한다.

이름이 어떤 버전을 나타내는지 확실치 않으면 InetAddressInet4Address 또는 Inet6Address의 인스턴스인지 확인하면 되는데, 이 작업은 주로 사용자가 제공한 주소에 대해서 수행된다.

마지막으로 짚고 넘어가야 한 사항은 이름 룩업과 역 룩업은 비용이 많이 드는 연산이라는 점이다. 시스템은 성능과 보안의 두 가지 이유에서 캐시 메커니즘을 이용한다. 일단 호스트를 룩업하면 동일한 결과를 얻게 되고 룩업 간에 결과를 변경할 수 없다는 점을 여러분은 잘 알고 있을 것이다.

"Java SE" 카테고리의 다른 글

Posted by 1010