'UDP'에 해당되는 글 5건

  1. 2008.04.02 UDP Socket-5.One-To-Many 네트워크 프로그램

One-To-Many 네트워크 프로그램

 

IP IP 멀티캐스팅

 

TCP/IP 프로토콜 수트중 IP가 제공하는 서비스는 어드레싱(Addressing)과 라우팅(Routing)

으로 요약할 수 있을 것입니다. 네트워크에 참여중인 컴퓨터들간에 정보를 주고 받을 때

네트워크로 보내진 정보가 출발지에서 목적지까지 도착하도록 해주는 것이 IP가 제공하는

서비스입니다.  IP는 네트워크에 참여한 컴퓨터를 IP 주소라는 개념으로 인식을 합니다.

인터넷에 참여하는 모든 컴퓨터는 IP주소를 가지고 있어야 하겠지요.

IP IP주소를 기준으로 정보를 배달하니까요.

 

현재의 인터넷에서 실제 사용중인 IP IPV4인데 IPV4 IP 주소는 A클래스, B클래스 ,

C클래스등으로 구분합니다.

상당히 있어보이는 대단한 구분 같지만,실제로 알고 보면 구분의 기준은 아무것도 아닙니다. 아주 간단하지요.

IP주소는 4바이트 즉, 32비트로 구성되어 있습니다. 8비트씩, 4개를 묶어서 부르는 것이

편하기 때문에 흔히 255.255.255.255등으로 비트가 아닌 숫자로 부릅니다.

8비트 모두가 1이면 십진수로는 255이기 때문에 255.255.255.255라고 부르는 주소는

실제로는 32비트가 모두 1인 주소를 말합니다.

 

IP 주소의 클래스 구분은 인터넷 주소를 32비트로 풀어놓았을 때 첫번째 비트가 0이면

A클래스 주소, 첫번째 비트가 1이고 두번째 비트가 0 이면 B클래스,첫번째 비트가 1이고

두번째 비트가 1이고 세번째 비트가 0이면 C클래스입니다.

임하룡, 심형래의 한문배우기에서처럼 작대기 하나면 일, 작대기 둘이면 이, 작대기 세개면

삼인것과 같습니다.

첫번째 비트가 0이면 두번째 비트부터 여덟번째 비트가 어떤 값을 가지든지 간에

십진수로는 0부터 127의 값을 가지게 됩니다.

그래서 0부터 127로 시작하는 IP 주소는 A 클래스주소입니다.

A 클래스의 첫 8 비트는 네트워크의 식별 주소이며, 나머지 24 비트는 네트워크안의

컴퓨터를 식별하는 정보입니다. IP 주소는 네트워크 부분과 호스트 부분으로 나뉩니다.

 

첫번째 비트가 1이고 두번째 비트가 0이면 세번째 비트부터 여덟번째 비트가 어떤 값을

가지든지 간에 십진수로는 128부터 191까지의 값을 가지게 됩니다.

그래서 128부터 191로 시작하는 IP주소는 B클래스 주소입니다.

B 클래스의 첫 16 비트는 네트워크 식별 주소이며, 나머지 16 비트는 네트워크 안의

컴퓨터를 식별하는 정보입니다.

 

첫번째 비트가 1이고 두번째 비트가 1이고 세번째 비트가 0이면 네번째 비트부터 여덟번째

비트가 어떤 값을 가지든지 간에 십진수로는 192부터 223까지의 값을 가지게 됩니다.

그래서 192부터 223까지로 시작하는 IP 주소는 C클래스 주소입니다.

C 클래스의 첫 24 비트는 네트워크 식별 주소이며, 나머지 8 비트는 네트워크 안의

컴퓨터를 식별하는 정보입니다.

 

아마 여러분의 컴퓨터에서 아마 127.0.0.0 이라는 네트워크를 보신적이 있을텐테 이

네트워크는 A 클래스 네트워크입니다. IP주소의 첫번째 부분이 0부터 127사이에 속해있기

때문이지요.

그리고 여러분은 127.0.0.0 뿐만 아니라 224.0.0.0 이라는 네트워크를 보신적이 있을

것입니다. 그런데 이 네트워크는 A클래스도, B클래스도, C클래스도 아닙니다.

주소의 첫번째 부분이 224이기 때문입니다. 이 네트워크는 D 클래스 네트워크입니다.

 

D 클래스는 임하룡,심형래의 한문배우기 규칙처럼 첫번째 비트가 1, 두번째 비트가 1,

세번째 비트가 1, 네번째 비트가 0인 것을 말합니다.

다섯번째 비트부터 여덟번째 비트가 어떤값을 가지더라도 224부터 239까지의 값을

가집니다. 그래서 224부터 239까지로 시작하는 IP주소는 D클래스 주소입니다.

 

D클래스 주소는 A클래스,B클래스,C클래스의 주소와 달리 인터넷에 참여하는 컴퓨터

마다 하나씩 주어지는 주소가 아닙니다.

D클래스의 주소는 IP 멀티캐스팅을 위한 주소입니다.

 

D클래스 주소는 특정한 컴퓨터를 의미하는 것이 아니라 특정한 서비스에 참여하는

네트워크라고 생각하면 간명할 것입니다.

그러니까 D클래스의 주소는 특정 컴퓨터를 지칭하는 것이 아니라 D클래스 주소로 대표되는

멀티캐스팅 네트워크, 즉 멀티캐스팅에 참여한 컴퓨터의 집단을 가리킵니다.

 

만약 어떤 프로그램에서 목적지를 D클래스 주소로 해서 네트워크로 정보를 보내면

정보는 특정한 컴퓨터를 대상으로 도착하는 것이 아니라, D 클래스 주소로 대표되는

IP 멀티캐스팅 네트워크에 참여하는 컴퓨터에게 모두 도달하게 됩니다.

하나의 컴퓨터에서 메시지를 D클래스 주소로 보내게 되면 D클래스 주소에 참여하는 컴퓨터

집단은 모두 메시지를 받아볼 수 있으므로 일대다의 통신이 가능한 것입니다.

 

짐작하셨겠지만 일대다의 특성은 그 근본적인 특성으로 인해 TCP기반에서는 절대로

일어날수 없고 (왜냐하면 연결을 반드시 해야한 하는 TCP로는 일대다의 개념이 있을 수 없

습니다.) UDP기반에서 일어날 수 있습니다.

자바에서는 이런 멀티캐스팅을 이용할 수 있도록 준비를 해놓았기 때문에 유니캐스팅 UDP

프로그램이나 멀티캐스팅을 이용한 UDP 프로그램이나 어렵지 않은 것은 매 한가지 입니다.

 

 

장나라 스케쥴 서버

 

여기서는 IP 멀티캐스팅을 이용한 UDP기반의 네트워크 프로그램을 만들어 보겠습니다.

인기가수이자 인기탤런트인 장나라양이 팬들을 위해서 자신의 하루의 일정을 인터넷으로

알려주는 서비스를 제공하기로 했습니다. 그런데 인기탤런트인 장나라양에게는 팬들이

굉장히 많고 만약 이런 서비스를 제공한다면 장나라양의 일정을 알고 싶어하는 팬들이

적극적으로 동참할 것입니다. 그래서 똑똑한 장나라양은 이런 상황일때는 IP 멀티캐스팅을

이용한 UDP기반의 프로그램이 적합하다는 것을 알고 프로그램을 개발하기 시작합니다.

 

장나라양이 개발하는 스케쥴 서버는 24시간 내내 IP 멀티개스팅 주소로 자신의 일정정보를

보냅니다.  일정이 많은 것은 아니니 약 1초마다 중요한 일정을 네트워크로 보냅니다.

만약 장나라양의 일정에 대해 궁금한 팬은 IP 멀티캐스팅 주소에 참여하기만 하면 장나라양

이 개발한 스케쥴 서버에서 알려주는 정보를 읽을 수 있습니다. (실제 현실에서는 IP

멀티캐스팅을 사용하는데는 제약이 있습니다. 하지만  같은 네트워크 에서는 얼마든지 사용

할 수 있습니다. 예제는 같은 네트워크에서 IP 멀티캐스팅을 이용합니다.)

마치 라디오 방송국에서 특정한 주파수에 계속 방송을 흘려보내고 있고, 라디오 방송국의

방송을 듣고자 하는 청취자는 라디오의 주파수를 방송국에서 송출하는 주파수에 맞추기만

하면 방송을 들을 수 있는 것과 같은 이치입니다.

 

장나라양의 일정을 알려주는 IP 멀티캐스팅을 이용한 UDP 기반의 네트워크 프로그램의

서버를 만들어 보겠습니다.

 

package udp;                                                                                                                              

 

import java.net.*;

import java.util.*;

import java.io.*;

 

 

/**

* 장나라의 스케쥴을 네트워크로 쓰는 스케쥴서버입니다.

* 멀티캐스팅 IP 주소는 임의로 "230.0.0.119"로 정했습니다.

*/

public class ScheduleServer {

             public static void main(String[] args) {

            

                           /* 장나라의 스케쥴을 데이타 소스에 추가합니다.*/

                           List schedule = new ArrayList();                                 

                           schedule.add("5 5일 오전 9,어린이 대공원 어린이날 기념 콘서트 참가");

                           schedule.add("5 5일 오후 3,KBS 뮤직박스 공개녹화");

                           schedule.add("5 5일 오후 7,생방송 MBC 스타와 토크진행");

                           schedule.add("5 5일 오후 9,선붕이와 놀기");

                          

                           /* 장나라의 스케쥴을 보내는 IP 멀티캐스팅 주소입니다.*/

                           String address = "230.0.0.119";          

                           try {

                                        Runnable r = new ScheduleTask(address, schedule);                

                                        Thread t = new Thread(r,"Schedule");            

                                        t.start();

                           }

                           catch(UnknownHostException uhe) {

                                        uhe.printStackTrace();

                           }

             }

}

예제 12 - 6 ScheduleServer.java

 

ScheduleServerudp기반의 네트워크 프로그램이므로 udp패키지에 속하게 했습니다.

 

첫번째가 224 239 사이에 있으니까 D클래스 주소인 IP 멀티캐스팅 주소입니다.

장나라 스케쥴 서버는 230.0.0.119 멀티캐스팅 주소로 장나라의 스케쥴정보를 보냅니다.

하지만 만약 장나라양의 팬들이 230.0.0.119로 보내는 정보를 받아보지 않는다면요?

물론 안받아보면 말고지요.

ScheduleServer는 서비스객체인 ScheduleTask Thread로 서비스로 IterativeServer형태로

구성했습니다.

 

 

package udp;                                                                                                                              

 

import java.net.*;

import java.util.*;

import java.io.*;

 

/**

* 장나라 일정을 알려주는 서비스객체

*/

public class ScheduleTask implements Runnable {                    

             /**

             * 장나라 일정을 알려주는 IP 멀티캐스팅 주소

             */

             private InetAddress group;                                                                    

            

             /**

             * 장나라의 일정을 갖고 있는 데이타소스

             */

             private List schedule ;                                  

            

             /**

             * IP 멀티캐스팅 주소로 장나라의 일정을 보내는 주기 m sec

             */

             private final long UNIT = 1000;                                                                

            

             /**

             * 장나라 일정을 알려주는 서비스 객체를 만듭니다.

             *

             * @param address IP 멀티캐스팅 주소

             * @param schedule 장나라의 일정을 갖고 있는 데이타소스

             */

             public ScheduleTask(InetAddress address, List schedule) {

                           this.group = address;

                           this.schedule = schedule;

             }

             /**

             * 장나라 일정을 알려주는 서비스 객체를 만듭니다.

             *

             * @param address IP 멀티캐스팅 주소

             * @param schedule 장나라의 일정을 갖고 있는 데이타소스

             */

             public ScheduleTask(String address, List schedule ) throws UnknownHostException {          

                           this(InetAddress.getByName(address),schedule);

             }

            

             /**

             * 장나라의 일정을 일정한 주기마다 IP 멀티캐스팅 주소로 보냅니다.

             */

             public void run() {

 

                          

                           DatagramSocket ds = null;

          try {                    

        ds = new DatagramSocket();                                                    

       

                       while (true) {

                                                     for(Iterator it = schedule.iterator(); it.hasNext();) {

                                                                  /* 장나라의 스케쥴을 네트워크로 보내려고 DatagramPacket

만듭니다.*/

                                                                  /* DatagramPacket에 장나라의 스케쥴을 담고는 IP 멀티캐스팅

주소에 UDP 서비스포트 8989로 네트워크 씁니다. */

                                                                 

                                                                  String result = (String)it.next();

                                                                  byte[] buf = result.getBytes();

                             DatagramPacket packet =

new DatagramPacket(buf, buf.length, group, 8989);

                            

                             /* 장나라의 스케쥴을 담은 DatagramPacket을 네트워크로 씁니다.*/

                             ds.send(packet);                                            

 

                                                                  /* 장나라의 다음 스케쥴을 보내기전에 일정기간 기다립니다.*/

                             Thread.sleep(UNIT * 1);                                  

                                                     }

                                                     /* 장나라의 모든 스케쥴을 네트워크로 쓴 후, 다음 스케쥴을 보낼때

                                                     까지 조금 오래 기다립니다.*/

                Thread.sleep(UNIT * 10);                                              

                                        }

                           }

                           catch(SocketException se) {

                                        se.printStackTrace();

                           }

                           catch(IOException ie) {

                                        ie.printStackTrace();

                           }

                           catch(InterruptedException ignore) {

                           }           

                           finally {

                                        /* 네트워크 자원을 해제합니다.*/

                                        if (ds != null)

                                                     ds.close();

                           }

             }

}

예제 12 - 7 ScheduleTask.java

 

서비스 객체 ScheduleTask UDP 기반의 네트워크 프로그램이므로 UDP 패키지에 속하게

했습니다. ScheduleTask public void run() 메소드는 반복문으로 구성되어 있어서

ScheduleTask를 실행하는 Thread는 종료하지 않고 계속 서비스 할 수 있습니다.

이는 서비스를 제공하는 서버의 공통적인 특징일 것입니다.

 

서비스 객체 ScheduleTask는 장나라양의 스케쥴 정보와 네트워크 정보를 

DatagramPacket에 담아 DatagramSocket을 이용해서 네트워크로 씁니다.

그리고 이와 같은 행동을 계속해서 반복합니다.

 

UDP를 이용하는 프로그램은 네트워크로 데이터를 읽고,쓰기전에 TCP 연결을  해야하는

TCP와 달리 언제 어떤때든 DatagramPacket 네트워크로 쓸 수 있습니다.

하지만 UDP 프로그램에서 DatagramSocket으로 보낸 DatagramPacket은 상대방에 도착

하지 못할 수도 있습니다. 심지어는 읽어줄 상대방이 없을 때도 있습니다.

 

반면 TCP 프로그램은 TCP 연결하는 과정이 필요하기 때문에 반드시 상대방이 있어야하고

TCP 연결이 되기 전에는 한 비트의 데이터조차 네트워크로 보낼수 없습니다.

반면 TCP 연결된 후에 읽고,쓰는 데이터는 항상 상대방에 도착합니다.

 

그림 12 - 5 ScheduleServer를 실행시킨 보습니다.

ScheduleServer는 매초 마다  IP 멀티캐스팅 주소로 장나라의 스케쥴 정보를 보냅니다.

보이시나요?

그림 12 - 5

 

ScheduleServer가 이미 장나라의 스케쥴정보를 IP 멀티캐스팅주소로 보내고 있으니까

장나라 팬이 만약 장나라의 스케쥴정보를 받아보려고 한다면 IP 멀티캐스팅 주소에 참여만

하면 됩니다.

이제 장나라양의 스케쥴을 받아보는 프로그램을 만들어 보겠습니다.

 

package udp;                                                                                                                                                                     

 

import java.io.*;

import java.net.*;

import java.util.*;

 

/**

* 장나라 일정을 알려주는 서비스인 IP 멀티캐스팅에 참여합니다.

* IP 멀티캐스팅으로 보내져오는 장나라의 일정을 읽고, 화면에

* 출력합니다.

*/

public class ScheduleListener {

 

    public static void main(String[] args) {

 

                           /* IP 멀티캐스팅 주소로 배달된 DatagramPacket을 읽을 수 있습니다.*/

        MulticastSocket ms = null;

       

        /* 참여하는 IP 멀티캐스팅 주소입니다.*/

                           InetAddress address = null;

                          

                           /* 네트워크로 부터 읽은 데이터를 담습니다.*/

        DatagramPacket packet = null;

 

                           try {

                                        /* IP 멀티캐스팅으로 DatagramPacket을 보낼수도 있고

                                        받을 수도 있는 DatagramSocket을 만들고, UDP 8989포트에

                                        BIND합니다. */

                                        ms = new MulticastSocket(8989);                                                                        

                                       

                                        /* IP 멀티캐스팅 주소 "230.0.0.119"에 참여합니다.*/

        address = InetAddress.getByName("230.0.0.119");                       

        ms.joinGroup(address);                                                                                                  

 

                                        while(true) {

                                                     /* IP 멀티캐스팅 주소로 배달되어온 데이타를 DatagramPacket으로

                                                     읽습니다.*/

                       byte[] buf = new byte[256];

                       packet = new DatagramPacket(buf, buf.length);

                       ms.receive(packet);                                                                                                        

 

                                                     /* DatagramPacket에 담긴 장나라의 스케쥴을 화면에 출력합니다.*/

                       String schedule = new String(packet.getData());           

                       System.out.println(schedule);                                                                

                       System.out.flush();

                                        }

        }

                           catch(IOException ioe) {

                                        ioe.printStackTrace();

                           }

                           finally {

                                        try {

                                                     /* 네트워크 자원을 해제합니다.*/

                                                     if (ms != null) {

                                    ms.leaveGroup(address);                                                                     

                                    ms.close();                                                                                                                   

                     }

                                        }

                                        catch(Exception ignore) { }

                           }

    }

}

예제 12 - 8 ScheduleListener.java

 

장나라의 스케쥴 정보를 받아보는 ScheduleListener 프로그램도 udp패키지에 속합니다.

예제 12 - 8에서는 DatagramSocket과 다른 MulticastSocket이 등장합니다.

MulticastSocket IP 멀티캐스팅 주소로 씌여진 DatagramPacket까지 읽고,쓸 수 있는

능력을 갖고 있는 DatagramSocket입니다. , MulticastSocket DatagramSocket

상속하여, DatagramSocket에 더하여 추가적인 기능을 갖고 있는 네트워크 객체입니다.

 

장나라 스케쥴 정보를 제공하는 서버가 UDP포트 8989번을 사용하므로 MulticastSocket

8989번에 바인드하는 MulticastSocket을 만듭니다.

그리고 MulticastSocket으로 하여금 장나라의 스케쥴정보를 제공하는 “230.0.0.119”

멀티캐스팅 네트워크에 참여합니다.

이렇게 “230.0.0.119” 멀티캐스팅 네트워크에 참여하게 되면 “230.0.0.119”로 씌여진

데이터를 읽을 수 있습니다.

 

ScheduleListener는 네트워크로부터 데이터를 읽는 형태를 취하고 있기 때문에 서비스를

받는 측면에서는 클라이언트이지만 프로그램의 구조는 오히려 일반적인 UDP 기반의

서버와 유사한 형태를 가집니다.

다만 멀티캐스팅 네트워크로 씌여진 데이터를 읽어낸다는 점에서 일반적인

DatagramSocket을 이용하지 않고 MulticastSocket을 이용하고 이를 이용해 멀티캐스팅

주소에 참여하는 과정이 추가되어 있을 뿐입니다.

 

그럼 아까 실행시켜놓은 장나라양의 스케쥴을 알려 주는 서버가 여전히 실행중이라면

지금 ScheduleListener를 실행시킨다면 그림 12 - 6처럼 장나라양의 스케쥴정보를 얻을 수

있습니다.

 

그림 12 - 6

Posted by
,