사용할 수 있습니다. 클라이언트는 NameServer가 준비해 놓은 ServerSocket으로
TCP연결을 하여 통신채널인 Socket을 만들어 내고, Socket으로부터 InputStream을 얻어내고 , 자바의 I/O를 이용해서 데이터를 읽어내면 그 읽어낸 정보가 바로 NameServer가 제공하는
서비스인 자신의 이름입니다.
그림 11 - 2를 보면 NameServer가 제공하는 서비스를 telnet 클라이언트를 통해서 사용
했는데, telnet 클라이언트는 원래는 NameServer가 제공하는 서비스를 받을 용도로 만들어
진 것은 아닙니다만 단순하게 TCP 연결을 해서 TCP 서버가 제공하는 데이터를 읽는데는
문제가 없었습니다. 이렇게 생각한다면 웹 브라우저 역시 웹서버와 HTTP 프로토콜로 통신
을 하는데 HTTP도 TCP의 서비스를 받고 있으니까 웹 브라우저를 통해서도 NameServer의
서비스를 받을 수 있습니다.
그림 11 - 4
말하고 싶은 핵심은 어떤 애플리케이션이 되었던 TCP의 서비스를 기반으로 만든
애플리케이션은 기본적으로 TCP연결을 한후에 읽고 쓰기를 합니다.
그런면에서 telnet 클라이언트이건, ftp 클라이언트이건, 웹 브라우저이건 모두 TCP기반의
네트워크 클라이언트이므로 TCP연결을 한후에 데이터를 읽고,쓰고 하는데, TCP 연결을
한후에 서버로부터 데이터를 읽는 정도의 기능만 있으면 되는 NameServer의 클라이언트로
충분히 사용할 수 있습니다.
지금까지 TCP 서버를 만들어보았고, TCP 클라이언트로 telnet, 웹 브라우저를 사용했는데
이제 네트워크로부터 데이터를 읽는 가장 기본적인 TCP 기반 클라이언트 프로그램을 만들
어 보겠습니다.
package tcp;
import java.io.*;
import java.net.*;
/**
* 클라이언트는 NameServer의 TCP 8988 서비스 포트로 TCP 연결을 시도합니다.
* 클라이언트가 TCP 연결을 하면 Socket객체를 얻을 수 있고, Socket 객체로 부터
* 데이터를 읽고,쓸수 있는 스트림을 얻을 수 있습니다.
* NameServer가 클라이언트에게 보내는 데이터인 서버의 이름을 읽어서 화면에
* 출력합니다.
*/
public class NameClient {
public static void main(String[] args) throws Exception {
Socket s = null;
InputStream is = null;
BufferedReader br = null;
try {
/* NameServer의 Listen Socket으로 TCP 연결
TCP 연결이 되면 Socket 객체를 리턴합니다. Socket - 통신채널
*/
s = new Socket("localhost", 8988);
is = s.getInputStream(); // Socket으로부터 얻은 InputStream
br = new BufferedReader(new InputStreamReader(is));
/*
* NameServer로부터 한 줄(newline)을 읽습니다.
*/
String msg = br.readLine();
System.out.println(msg);
}
catch(IOException ie) {
ie.printStackTrace();
}
finally {
/*
시스템 자원을 해제합니다.네트워크 자원을 해제합니다.
*/
try {
if (is != null)
is.close();
if (br != null)
br.close();
if (s != null)
s.close();
}
catch(Exception e) {
e.printStackTrace();
}
}
}
}
예제 11 - 2 NameClient.java
NameClient 역시 TCP 기반의 프로그램이어서 tcp 패키지에 속해있습니다.
NameClient가 제일 먼저 하는 것은 NameServer가 Listen하고 있는 컴퓨터의 TCP 포트
8988로 TCP연결을 하는 겁니다. 즉, NameClient는 여기서 Socket 객체를 만들고 있는
데, NameServer가 Socket 객체를 얻는 것과는 사뭇 다릅니다.
NameClient는 적극적으로 Socket 객체를 만들고 있고, NameServer는 ServerSocket을
만든후, public Socket accept() 메소드를 호출한 뒤, 클라이언트가 TCP 연결을 해주기를
줄창 기다립니다. 언젠가 클라이언트가 TCP 연결을 해주면 서버는 비로소 Socket 객체를
얻을 수 있습니다.
TCP연결을 맺은 후 네트워크로부터 InputStream, OutputStream을 얻어야 읽고,쓰기를
할 수 있는데, 자바에서 TCP 네트워크 연결을 객체로 표현한 것이 Socket 객체입니다.
이렇게 TCP 연결이 되면 만들어지는 것이 Socket 객체이고, Socket 객체만 있으면
InputStream, OutputStream을 얻을 수 있어서, 읽고 쓰기를 자유롭게 할 수 있습니다.
TCP 기반의 네트워크 프로그램의 핵심인 Socket 객체를 만드는 것은 아주 간단합니다.
Socket의 오버로딩된 생성자중 하나는 메소드 인자로 String형 IP 주소와 int형 TCP 포트
를 사용하는데, 이 Socket객체를 생성하는 것이 바로 IP 주소로 대표되는 네트워크상의
컴퓨터, 그 컴퓨터의 TCP 포트로 대표되는 서비스를 제공하는 서버(애플리케이션)로 TCP
연결을 시도하는 겁니다.
NameClient는 Socket 객체를 얻은 후에 InputStream을 얻고, NameServer 보내는 한줄의
데이터를 읽기위해서 public String readLine() 메소드를 갖고 있는 BufferedReader 객체를
사용합니다.
읽은 데이터를 화면에 출력하고, 종료하기 전에 네트워크 자원을 모두 해제합니다.
그림 11 - 5
그림 11 - 5는 tcp.NameClient를 실행시킨 결과입니다.
물론 tcp.NameClient를 실행하기 전에 tcp.NameServer가 먼저 실행되어 있어야 하겠지요.
항상 서버가 클라이언트보다 먼저이니까 말입니다.
'자바 Network Programming' 카테고리의 다른 글
Socket-7.TCP 클라이언트와 TCP 서버의 간단한 구조 (0) | 2008.03.28 |
---|---|
Socket-6.TCP 네트워크로부터 읽고 쓰기 (0) | 2008.02.04 |
Socket-4.TCP Socket 서버 만들기 (0) | 2008.01.23 |
Socket-3.서버 vs 클라이언트 (0) | 2008.01.23 |
Socket-2.프로토콜 (0) | 2008.01.23 |