Skill/Programming - Network

24. IP 멀티캐스트

gyulee0220 2019. 10. 20. 13:58


1. IP Cast

  우리가 지금껏 배운 네크워크 연결은 모두 송신지 IP 주소와 수신지 IP 주소가 존재했다. 그리고 IP 주소를 입력하는 공간에는 단 하나의 주소만 입력할 수 있었다. 즉, 지금까지의 송수신은 모두 One to One 방식이었다.


  하지만, 같은 정보를 여러명에게 전달해야 하는 경우도 분명 존재할 것이다. 예를들어 우리가 프리미어리그 스트리밍 경기를 네트워크를 통해 본다고 가정해보자. 스트리밍 제공자가 각각의 클라이언트와 1:1로 연결을 해야 한다면, 각 사용자에게 따로따로 데이터를 만들어 전달해줘야한다. 제공자 입장에서 엄청난 데이터를 사용해야 하는 불편함이 소모된다.


  이를 해결하기 위한 좋은 방법이 한명의 송신자와 여러명의 수신자를 동시에 연결시켜 전송 한번으로 여러명의 사용자가 이를 듣는 방법을 구현할 수 있다. 멀티캐스트는 위를 구현하기 위한 최적의 방법이다.


 IP 캐스트는 총 3가지가 존재한다.


- Unicast


  한명의 송신자와 수신자가 존재하는 1:1 데이터 전달 방식이다. 기본적으로 유니캐스트는 소켓 통신을 기반으로 하고 있기 때문에, 데이터 링크 계층에서 적용된다. 유니캐스트 방식에선 데이터를 주고받을 때, 소켓간의 데이터 통신을 통해 MAC Address 일치 여부를 파악한다. MAC address가 일치하는 경우 CPU에 데이터를 올리게 되고, 그렇지 않은 경우 데이터를 삭제한다. 그리고 MAC Address 불일치로 데이터가 버려지는 것을 유니캐스트 플루드 (Unicast Flood)이라고 한다. 


- Multicast


  멀티캐스트 방식은 일정 그룹으로 지정된 IP에 송신자가 동시에 데이터를 보내주는 방식을 의미한다. 개념적으로 광범위하게 보자면 한명의 송신자가 여러명의 수신자에게 보내게 되는 모든 통신 형태를 멀티캐스트라고 한다. 주로 우리가 언급하게되는 IP 멀티캐스트는 주로 데이터 링크 계층에서 소켓 통신으로 존재한다. 기본적으로 송신 측에서는 패킷을 한번만 전송해야 한다. 그리고 이러한 멀티캐스트는 라우터에서 수행하므로 개발자는 크게 신경쓰지 않아도 된다.


- Broadcast


  송신 호스트에서 전송을 하게 되면 연결되어 있는 모든 네트워크에 패킷이 도달하게 되는 통신 방식을 의미한다. 유니캐스트가 MAC Address가 불일치 하는 경우 패킷을 플루딩하게 되는데, 브로드캐스트는 정반대로 MAC address 확인 작업 없이 모든 데이터를 받아들이게 된다. 브로드캐스트의 MAC address는 FF:FF:FF:FF:FF:FF: 로 고정되어 있다.



2. 멀티캐스트의 그룹

  데이터를 수신받을 호스트 그룹의 공유 주소. 224.0.0.0 부터 239.255.255.255안에 속해 있다. 멀티캐스트 구현을 위해서는 해당 주소 안에서 구현해야 한다. 또한 이는 IANA (Internet Assigned Number Authority)에서 관리한다.


<링크 로컬 멀티캐스트 주소>


   도메인 이름

  IP 주소 

  목적 

 BASE-ADDRESS.MCAST.NET

 224.0.0.0

 어떠한 멀티캐스트 그룹에도 할당되지 않는 베이스 주소

 ALL-SYSTEMS.MCAST.NET

 224.0.0.1

 로컬 서브넷의 모든 시스템

 ALL-ROUTERS.MCAST.NET

 224.0.0.2

 로컬 서브넷의 모든 라우터

 DVMRP.MCAST.NET

 224.0.0.4

 DVMRP 라우터 (최초로 개발된 멀티캐스트 라우터)

 DHCP-AGENTS.MCAST.NET

 224.0.0.12

 DHCP 서버나 전달 에이전트에 넣는 멀티캐스트

 VRRP.MCAST.NET

 224.0.0.18

 VRRP(Virtual Router Redundancy Protocol) 라우터

 224.0.0.254

 실험용 멀티캐스트 주소


<영구 할당된 멀티캐스트 주소>


   도메인 이름

  IP 주소 

  목적 

 NTP.MCAST.NET

 224.0.1.1

 네트워크 타임 프로토콜

 NSS.MCAST.NET

 224.0.1.6

 네임 서비스 서버 

 AUDIONEWS.MCAST.NET 224.0.1.7 

 오디오 뉴스 멀티캐스트 

 MTP. MCAST.NET

 224.0.1.9 

 멀티캐스트 전송 프로토콜 

 MTRACE.MCAST.NET

 224.0.1.32 

 traceroute의 멀티캐스트 버전 

 

 239.0.0.0 ~ 239.255.255.255

 사설 멀티캐스트 주소


3. 멀티캐스트 사용

- TTL


  멀티캐스트를 구현하기 위해서는 필수적으로 TTL (Time to Live) 값이 설정이 되어야 한다. 여기서 TTL은 패킷이 거쳐갈 수 있는 라우터의 개수를 의미한다. 기본적으로 멀티캐스트 패킷의 TTL은 1로 설정되어 있기 때문에 로컬 호스트를 벗어나지 못하게 된다.


- 라우팅


  실제 네트워크 환경은 중복될 라우터가 수없이 많은 계층 구조로 이루어져 있기 때문에 라우팅 과정이 매우 목잡하다. 하지만 몰티캐스트 소켓을 쓰게된다면 동일한 데이터를 여러번 보내는 수고를 덜 수 았게 된다. 라우터에 멀티 캐스트 소켓을 사용하게 된다면, 해당 라우터랑 연결된 모든 네트워크에 한번의 송신으로 데이터를 전달 할 수 있게된다. 즉, 같은 네트워크 안에 존재한다면 여러번 데이터를 전달해야 하는 작업을 단 한번으로 줄일 수 있게 되는 것이다.


- 멀티캐스트 소켓 구현

 

  Java에선 멀티캐스트 구현을 위한 java.net.MulticastSocket 클래스가 존재한다. 이를 이용해 데이터 멀티캐스트를 구현할 수 있다.


public class MulticastSocket extends DatagramSocket implements Closeable, AutoCloseable


  생성된 멀티캐스트의 데이터 수신을 위해서는 MulticastSocket() 메소드를 통해 Multicast Socket을 만든다. 파라미터에는 포트 번호를 입력한다.


MulticastSocket socket = new MulticastSocket(2300);


  생성된 멀티캐스트 소켓을 멀티캐스트 그룹 중 한 곳에 지정을 해주어야 한다.


InetAddress group = InetAddress.getByName("224.2.2.2");

socket.joinGroup(group);


  그 다음 그룹에 속한 호스트들에게 데이터를 전송시켜야 한다. 메소드는 send()이다.


socket.send(packet);


  반대로 데이터를 수신하는 메소드는 receive()이다.


socket.receive(packet);


  멀티캐스트 수신을 더이상 원하지 않는 경우 그룹에서 탈퇴하면 된다.


socket.close();


   즉, 멀티캐스트 소켓에서 데이터 패킷을 주고 받는 과정을 정리하면 아래와 같다.


  1. 멀티캐스트 그룹에 가입한다.
  2. 멀티캐스트 데이터를 수신 받는다.
  3. 멀티캐스트 데이터를 송신한다. (위 2과정은 서로 바뀌어도 무방하다.)
  4. 멀티캐스트 그룹에서 탈퇴한다.


4. 멀티캐스트 예제

  단순한 멀티캐스트 연결은 아래와 같은 과정으로 연결이 가능하다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
 
public class Solution {
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
 
        InetAddress group = null;
        int port = 2300;
        
        try {
            group = InetAddress.getByName("224.2.2.2");
            
        } catch(Exception ex) {
            System.err.println("Error!");
            System.exit(1);
        }
        
        MulticastSocket socket = null;
        
        try {
            socket = new MulticastSocket(port);
            socket.joinGroup(group);
            
            byte[] buffer = new byte[8192];
            while (true) {
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                socket.receive(packet);
                String string = new String(packet.getData(), "8859_1");
                System.out.println(string);
                
            }
            
        } catch (IOException ex) {
            System.err.println(ex);
        } finally {
            if (socket != null) {
                try {
                    socket.leaveGroup(group);
                    socket.close();
                } catch (IOException ex) {}
            }
        }
        
        
    }
 
}
 
cs


출처 : Java Network Programming - 엘리엇 러스티 해럴드 (O'REILLY)