TCP Socket 프로그래밍

Socket  vs  ServerSocket

 

 Socket TCP를 이용하여 네트워크 스트림으로부터 읽고,쓰기를 할 수 있도록 한 객체

입니다.

일단 Socket이 만들어지면 Socket으로부터 네트워크 스트림인 InputStream,OutputStream

얻을 수 있습니다. InputStream, OutputStream을 얻은 이후 부터는 자바에서 제공하는

I/O 객체를 이용해서 읽고,쓰기를 합니다. 여기부터는 일반적인 자바 I/O를 하는 것이

바로 네트워크로부터 I/O를 하는 것과 같습니다.  이런 이유로 자바에서 TCP를 이용해서

네트워크 읽고,쓰기를 한다면 어떻게 Socket을 만들어 내느냐는 문제에 집중하면 됩니다.

Socket을 만들어낸다는 것은 클라이언트와 서버가 읽고 쓸 수 있는 통신 채널을 확보한다는

것과 같습니다.

이 통신 채널을 확보하기 위해서는 클라이언트와 서버가 적절한 준비를 해야합니다.

그 중 서버가 해야하는 준비는 ServerSocket을 만드는 일입니다.

 

TCP 서버 만들기

 

NameServer TCP를 이용한 네트워크에서 읽고,쓰기의 예를 보여주는 프로그램입니다.

NameServer는 네트워크를 이용해서 읽고,쓰기를 하려고 할 때 서버의 역할을 합니다.

 

TimeServer tcp 패키지에 속해 있습니다. TCP를 이용한 네트워크 프로그램은

tcp 패키지에 속하도록 하겠습니다.

 

 

package tcp;                                                            

 

import java.io.*;

import java.net.*;

import java.util.*;

 

/**

* 클라이언트에게 자신의 이름을 알려주는 서버입니다.

* 8988 TCP 포트를 Listen합니다. 클라이언트가 TCP 연결을 하면 자신의 이름을

* 클라이언트에게 보냅니다.

*/

public class NameServer {

            

             public static void main(String[] args) {

                          

                           ServerSocket ss = null;                    

                           Socket s = null;                              

                           OutputStream os = null;                    

                           PrintStream ps = null;                      

                           try {

                                        ss = new ServerSocket(8988);// NameServer Listen Socket - ServerSocket                       

                                       

                                        /* 클라이언트로부터 TCP 연결을 기다립니다. TCP 연결이 되면

                                        Socket객체를 리턴합니다.*/

                                        s = ss.accept();                                            // NameServer와 클라이언트의 Socket - 통신채널                                                                        

                                        os = s.getOutputStream();    // Socket으로부터 얻은 OutputStream                                                   

                                        ps = new PrintStream(os);               

                                        ps.println("안녕, 내 이름은 귀염둥이 \"크로커다일이야\"");                                                                                   

                                        ps.flush();                                                                                                                                                             

                           }

                           catch(IOException ie) {

                                        ie.printStackTrace();          

                           }

                           finally {

                                        /*

                                        시스템 자원을 해제합니다.(네트워크 자원을 해제합니다.

                                        */

                                        try {

                                                     if (ss != null)

                                                                  ss.close();

                                                     if (os != null)

                                                                  os.close();

                                                     if (ps != null)

                                                                  ps.close();

                                                     if (s != null)

                                                                  s.close();

                                        }

                                        catch(Exception e) {

                                                     e.printStackTrace();

                                        }

                           }

             }

}

예제 11 - 1 NameServer.java

 

NameServer public static void main(String[] ) 메소드의 ServerSocket 부분을 살펴보겠습니다.

ServerSocket에는 인자에는 수형의 값 8988이 지정되어 있습니다. 8988의 숫자의 의미는

TCP 포트를 의미합니다. 일반적으로 TCP 프로토콜에서 TCP 포트는 서버가 제공하는

서비스를 의미한다고 봅니다.

웹서버가 제공하는 서비스는 TCP 포트 80, FTP서버가 제공하는 서비스는 TCP 포트 21,

Telnet 서버가 제공하는 서비스는 TCP 포트 23, 메일서버(SMTP)가 제공하는 서비스는

TCP 포트 25, Echo 서버가 제공하는 서비스는 TCP 포트 7 등 유명한 서비스들은 모두

유명한 TCP 포트번호를 갖고 있고, 이를 well known 포트라고 합니다.

이런 포트들의 의미는 전 세계적으로 약속을 해 놓아서 모든 클라이언트가 알고 있습니다.

만약 자바로 웹서버를 만드는 경우 ServerSocket TCP 포트번호는 80, FTP서버를 만드는

경우 ServerSocket TCP 포트번호는 21일 것입니다.

예제 11 - 1 NameServer가 제공하는 서비스는 TCP 포트를 8988로 정했습니다.

 

ServerSocket의 인자인 8988, TCP 8988 포트는 서버의 이름을 알려주는 서비스를

의미합니다. TCP 8988 포트는 well known 포트가 아니라 사용자 포트입니다.

, 전 세계적으로 이미 약속이 정해져 있는 의미 있는 포트가 아니라 NameServer

맘대로 정해 버린거죠. 그래서 NameServer를 만든 프로그래머는 NameServer의 서비스를

받고 싶어하는 클라이언트가 있다면 전화로 알려주던 메일로 알려주던 어떤 형태로든

클라인언트를 만드는 프로그래머에게 TCP 연결을 할 수 있도록 ServerSocket TCP 포트

번호를 알려주어야 합니다.

 

일단 ServerSocket을 만든 후에는 클라이언트로부터 TCP 연결을 기다려야 합니다.

서버는 삶의 대부분을 여기서 보냅니다. 즉 클라이언트로부터 서비스 요청이 올때까지

기다리는게 삶의 대부분이죠. 일단 클라이언트로부터 TCP 연결이 되면 Socket을 리턴합니다.

일단 Socket이 리턴되면 그 Socket을 이용해서 읽고,쓰기를 할 수 있습니다.

NameServer가 클라이언트에게 데이터를 쓰려고 할때는 Socket으로부터 OutputStream

얻어내면 되고, 클라이언트로부터 데이터를 읽으려 할때는 Socket으로부터 InputStream

얻으면 됩니다.

NameServer OutputStream을 구한다음 자바 I/O객체중 하나인 PrintStream에 선언된

메소드인 public void println()을 이용해서 클라이언트에게 자신의 이름을 씁니다.

NameServer가 클라이언트에게 제공하는 서비스는 자신의 이름을 알려주는 겁니다.

그림 11 - 1

 

사용자 삽입 이미지

그림 11 - 1 NameServer를 실행한 모습입니다. tcp.NameServer s.accept()에서

블록되어 있을 것입니다. TCP/IP 네트워크상의 어떤 클라이언트가 TCP 연결을 하기만

기다리고 있습니다.

 

그림 11 - 2는 유명한 telnet 클라이언트를 이용해서 NameServer의 서비스를 받으려고

시도하는 모습입니다.

사용자 삽입 이미지

그림 11 - 2

 

그림 11 - 3 telnet 클라이언트를 이용해서 NameServer가 제공하는 정보를 얻은

결과입니다.

사용자 삽입 이미지

그림 11 - 3

telnet 클라이언트는 TCP의 서비스를 받는 프로그램이기 때문에 어쨌든 서버와 TCP

연결을 먼저한후에 telnet 서버와 텔넷 프로토콜로 통신을 할 겁니다.

여기서는 서버가 telnet 서버는 아니지만 TCP 네트워크 연결을 이용해서 NameServer

주는 메시지를 읽어보였습니다.

'자바 Network Programming' 카테고리의 다른 글

Socket-6.TCP 네트워크로부터 읽고 쓰기  (0) 2008.02.04
Socket-5.TCP 클라이언트 만들기  (0) 2008.02.01
Socket-3.서버 vs 클라이언트  (0) 2008.01.23
Socket-2.프로토콜  (0) 2008.01.23
Socket-1.네트워크  (0) 2008.01.23
Posted by
,