NameServer가 제공하는 서비스는 TCP/IP 프로토콜을 준수하는 네트워크 어디에서든

사용할 수 있습니다. 클라이언트는 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가 먼저 실행되어 있어야 하겠지요.

항상 서버가 클라이언트보다 먼저이니까 말입니다.

Posted by
,