멀티캐스트 (Multicast)

Network/Network 2011. 11. 2. 17:10

내가 인터넷 방송국을 운영한다고 가정하고,

클라이언트가 조낸 늘어났다고 가정해보자... N명이라고 칭하자.

TCP 기반으로 다중 접속 서버를 구성하면 N개의 소켓이 필요하고

UDP 기반으로 다중 접속 서버를 구성하더라도 1개의 소켓으로 N번의 전송을 해야만 한다.

 

인터넷 방송국이기 때문에 전송되는 데이터들은 모두 동일하다.

동일하게 전송해야될 거를 send를 미친듯이 써서 보내는 것은 좀 그렇다.

 

이러한 문제를 라우터 차원에서 해결했다.

이는 멀티캐스트라고 불린다. 이 것은 UDP를 기반으로 한다.

서버쪽에서는 Multicast packet을 한 번 보내기만 하면

라우터에서 열라 늘려서 N명에게 짜잔하고 동시에 쫙 뿌린다.

여기서 이 패킷의 목적지는 Multicast group에 포함되어있는 모든 호스트들이다.

 

 

1] 전송 방식

Multicast group이란 클래스D (224.0.0.0 ~ 239.255.255.255)에 속하는 IP주소 그 자체를 뜻한다.

멀티캐스트 패킷을 받으려면, 이 그룹에 가입해야된다.

응? IP주소에 가입해야된다는 사실이 좀 말이 안되지 않냐고 물어볼테지만 개념상 그런 것이다.

Multicast packet이란 이러한 multicast group가 목적지로 설정되어있는 UDP packet이다.

 

하지만 멀티캐스트는 단순히 multicast group을 목적지로 설정해서 보내는 것만으로

이루어지지 않는다. 왜냐하면 대부분의 라우터가 멀티 캐스트를 지원하지 않거나

또는 트래픽 문제를 고려해서 일부러 막아놓기 때문이다.

(외부 네트워크의 상태도 고려해야된다...)

 

 

2] 라우팅과 TTL

Multicast packet을 전송하려면 TTL 설정 과정을 반드시 거쳐야한다.

이 값은 몇 개의 라우터를 거칠 수 있느냐를 결정하는 값이다.

멀티캐스트가 아닌 지금까지 했뜬 유니캐스트에서는 이 TTL이 얼만지 모르겠는데

멀티캐스트로 보내는 패킷은 TTL이 기본적으로 1로 잡혀있기 때문에

로컬 호스트를 벗어나지 못한다.

 

 

3] 멀티캐스트 서버 클라이언트

시나리오>

Sender: A라는 Multicast group으로 데이터를 방송(멀티캐스트)한다.

Receiver: Multicast group에 가입(join)하고 뉴스를 수신한다.

 

 

/* Sender 소스의 일부분 */

 

//그냥 유니캐스트처럼 보낸다고 생각.
//멀티캐스트 패킷인지 아닌지는 커널이 결정하는 것이다. (커널이 TTL을 다르게 할당하는 듯)
memset(&multiAddr, 0, sizeof(multiAddr));
multiAddr.sin_family = AF_INET;
multiAddr.sin_addr.s_addr = inet_addr(argv[1]);        //Multicast group 설정
multiAddr.sin_port = htons(atoi(argv[2]));                 //port도 일치시켜야 한다.

 

//setsockopt로 멀티캐스트 패킷의 TTL을 설정.
state = setsockopt(hSendSock, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&multiTTL,

                          sizeof(multiTTL));

 

//이후로 sendto를 해서 멀티캐스트를 하면 된다.

 

 

 

/* Receiver 소스의 일부분 */

 

memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);//자기 자신? 바로 Multicast group을 안 넣네? 
addr.sin_port = htons(atoi(argv[2]));                              //포트도 일치시켜야 한다.

if(bind(hRecvSock, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR)
     ErrorHandling("bind() error");

 

//멀티캐스트 그룹 가입을 위한 구조체
joinAddr.imr_multiaddr.s_addr = inet_addr(argv[1]);    //argv[1] is Multicast group (=IP addr)
joinAddr.imr_interface.s_addr = htonl(INADDR_ANY);  //자기 자신
 
//setsockopt()로 멀티캐스트 그룹에 가입할 수 있다.
state = setsockopt(hRecvSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&joinAddr,

                          sizeof(joinAddr));

 

//이후로 이 Multicast group으로 멀티캐스트되는 것은로오는 것은

//hRecvSock으로 recvfrom할 수 있다.

'Network > Network' 카테고리의 다른 글

소켓 함수 모음  (0) 2011.11.11
struct sockaddr, sockaddr_in, sockaddr_un  (0) 2011.11.07
X25 와 TCP/IP  (0) 2011.08.26
NAS SAN SATA SCSI 방식 차이점  (0) 2010.04.06
네트워크 로드 밸런싱 시스템  (0) 2010.04.06
: