본문 바로가기

JAVA/네트워크 프로그래밍

[JAVA] 소켓 주소 및 프록시 서버(Client)

SocketAddress 클래스는 연결 끝점(endpoint)를 나타낸다. 이 클래스는 추상클래스 이다.


사실상 현재는 TCP/IP 소켓만이 지원되며, 우리가 사용하는 소켓 주소들은 전부 InteSocketAddress의 인스턴스이다.



SocketAddress 클래스를 사용하는 목적은 원본 소켓의 연결이 끊어지거나 GC(Garbage Collector)에 의해 사라진 경우에도 새로운 소켓을 생성하는 데 재사용할 수 있는 IP 주소와 포트 같은 일시적인 소켓 연결 정보를 위한 간편한 저장소를 제공하기 위함이다.


이를 위해서 Socket 클래스는 SocketAddress 객체를 반환하는 두 개의 메소드를 제공한다.


public SocketAddress getRemoteSocketAddress()

//연결된 시스템에 대한 주소를 반환한다.

public SocketAddress getLocalSocketAddress()

//연결을 만든 곳의 주소를 반환한다.


이 두 메소드는 소켓이 아직 연결되지 않은 경우에는 Null을 반환한다. 간단한 예로 네이버에 연결하고 주소를 반환한다.


Socket socket = new Socket("www.naver.com", 80);

SocketAddress naver = socket.getRemoteSocketAddress();

socket.close();


나중에 이 주소를 사용하여 다시 네이버에 연결할 수 있다.


Socket socket2 = new Socket();

socket2.connect(naver);


InetSocketAddress 클래스는 SocketAddress의 유일한 서브클래스이다. 이 클래스는 일반적으로 클라이언트의 경우에 호스트와 포트 또는 서버의 경우에 포트만 사용하여 만들어진다.


public InetSocketAddress(InetAddress address, int port)

public InetSocketAddress(String host, int port)

public InetSocketAddress(int port)


그리고 DNS에서 해당 호스트를 검색하는 과정을 생략하기 위해서 정적 팩토리 메소드 InetSocketAddress.createUnresolved() 또한 사용할 수 있다.


public static InetSocketAddress createUnresolved(String host, int port)


InetSocketAddress는 객체를 확인하는 데 사용할 수 있는 일부 get 메소드를 제공한다.


public final InetAddress getAddress()

public final int             getPort()

public final String         getHostName()



프록시 서버


Socekt 클래스의 마지막 생성자는 매개변수로 전달된 프록시 서버를 통해 연결하는 연결되지 않은 소켓을 생성한다.


public Socket(Proxy proxy)


보통 소켓이 사용하는 프록시 서버는 socksProxyHost와 socksProxyPort 시스템 속성에 의해 제어된다.


그리고 이 속성들은 시스템에 있는 모든 소켓에 적용된다. 그러나 이 생성자에 의해 생성된 소켓은 대신 매개변수로 지정된 프록시 서버를 사용한다.


주목해야 할 점은, 매개변수로 Proxy.NO_PROXY를 전달하면 모든 프록시 서버 설정을 무시하고 원격 호스트에 직접 연결할 수 있다. 물론, 방화벽이 직접적인 연결을 차단할 경우에는 실패한다.


특정 프록시 서버를 사용하기 위해서는 해당 서버의 주소를 지정하면 된다. 예를 들어, 다음 코드는 login.ibiblio.org 호스트에 접속하기 위해 myproxy.example.com에 위치한 SOCKS 프록시 서버를 사용한다.


SocketAddress proxyAddress = new InetSocketAddress("myproxy.example.com", 1000);

Proxy proxy = new Proxy(Proxy.Type.SOCKS, ProxyAddress)

Socket s = new Socket(proxy);

SocketAddress remote = new InetSocketAddress("login.ibiblio.ogr", 25);

s.connect(remote);

자바는 저수준 프록시 타입 중에서 SOCKS 프록시를 유일하게 지원한다.


그리고 전송 계층에서 동작하는 SOCKS 프록시 이외에도 애플리케이션 계층에서 동작하는 고수준 Porxy.Type.HTTP역시 지원한다.


마지막으로 Proxy.Type.DIRECT는 프록시를 사용하지 않는 연결을 나타낸다.