[Network] 14. 멀티캐스트 & 브로드캐스트

2023. 5. 28. 22:45

 

멀티캐스트 (Multicast)

멀티캐스트 데이터 전송방식과 트래픽 이점

  • 멀티캐스트 서버는 특정 멀티캐스트 그룹을 대상으로 데이터를 딱 한번 전송한다.
  • 딱 한번 전송해도 그룹에 속하는 모든 클라이언트가 데이터를 받는다.
  • 멀티캐스트 그룹의 수는 IP 주소 범위 내에서 얼마든지 추가가 가능하다.
  • 특정 멀티캐스트 그룹으로 전송되는 데이터를 수신하려면 해당 그룹에 가입하면 된다.

연결의 개념보다는 그룹에 가입한다는 개념이기 때문에 TCP 보다 UDP 소켓 기반으로 구현해야한다.

 

라우팅과 TTL

TTL : time to live
패킷을 얼마나 멀리 보낼 것인지 결정하는 요소이다.
TTL은 정수로 표현되며, 라우터를 하나 거칠때마다 1씩 감소되고 0이 되면 소멸한다.

 

int send_sock;
int time_live =64;

send_sock = socket(PF_INET, SOCK_DGRAM, 0);
setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (void*)&time_live, sizeof(time_live));

 

멀티캐스트 그룹 가입 방법

소켓의 옵션 정보 변경을 통해 이루어진다. 그룹의 가입에 사용되는 프로토콜 레벨은 IPPROTO_IP이고 프로토콜의 이름은 IP_ADD_MEMBERSHIP이다. 

int recv_sock;
struct ip_mreq join_adr;
recv_sock = socket(PF_INET, SOCK_DGRAM, 0);

join_adr.imr_multiaddr.s_addr = "multicast group address"
join_adr.imr_interface.s_addr="host address info"

setsockopt(recv_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&join_adr, sizeof(join_adr));

 

정리하자면 멀티캐스트를 위해서 sender는 IP_MULTICAST_TTL로 TTL을 설정해줘야하고 receiver는 IP_ADD_MEMBERSHIP으로 그룹에 가입해야한다.

 

멀티캐스트 Sender

send_sock = socket(PF_INET, SOCK_DGRAM, 0);
memset(&mul_adr, 0, sizeof(mul_adr));
mul_adr.sin_family=AF_INET;
mul_adr.sin_addr.s_addr=inet_addr(argv[1]]);
mul_adr.sin_port=htons(atoi(argv[2]));

setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (void*)&time_live, sizeof(time_live));
if((fp=fopen("news.txt", "r")) ==NULL)
	error_handling("fopen() error");
    
 while(!feof(fp))
 {
 	fgets(buf, BUF_SIZE, fp);
    sendto(send_sock, buf, strlen(buf), 0, (struct sockaddr*)&mul_adr, sizeof(mul_adr));
    sleep(2);
}

 

멀티캐스트 Receiver

recv_sock = socket(PF_INET, SOCK_DGRAM, 0);
memset(&adr, 0, sizeof(adr));
adr.sin_family=AF_INET;
adr.sin_addr.s_addr=htonl(INADDR_ANY);
adr.sin_port=htons(atoi(argv[2]));

if(bind(recv_sock, (struct sockaddr*)&adr, sizeof(adr))==-1)
	error_handling("bind() error");

join_adr.imr_multiaddr.s_addr=inet_addr(argv[1]);
join_adr.imr_interface.s_addrhtonl(INADDR_ANY);

setsockopt(recv_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void*)&join_adr, sizeof(join_adr));

while(1)
{
	str_len = recvfrom(recv_sock, buf, BUF_SIZE-1, 0, NULL, 0);
    if(str_len < 0)
    	break;
    buf[str_len]=0;
    fputs(buf, stdout);
}

 

브로드캐스트

브로트캐스트

동일한 네트워크 내에 존재하는 호스트에게 데이터를 전송하는 기법이다.
데이터 전송의 대상이 호스트가 아닌 네트워크이며, UDP 소켓을 기반으로 한다.
IP 에서 네트워크 주소를 제외한 호스트 주소를 모두 1로 전송하면 해당 네트워크로 전송된다.(directed broadcast)
255.255.255.255로 전송하면 호스트가 속한 네트워크로 전송된다. (local broadcast)

 

브로드캐스트 Sender

send_sock = socket(pF_INET, SOCK_DGRAM, 0);
memset(&broad_adr, 0, sizeof(broad_adr));

broad_adr.sin_family=AF_INET;
broad_adr.sin_port = htons(atoi(argv[2]));
broad_adr.sin_addr.s_addr = inet_addr(argv[1]);

setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST, (void*)&so_brd, sizeof(so_brd));
if((fp=fopen("news.txt", "r"))==NULL)
	error_handling("fopen() error");

while(!feof(fp))
{
	fgets(buf, BUF_SIZE, fp);
    sendto(send_sock, buf, strlen(buf),0, (struct sockaddr*)&broad_adr, sizeof(broad_adr));
    sleep(2);
}

 

브로드캐스트 Receiver

recv_sock = socket(PF_INET, SOCK_DGRAM, 0);
memset(&adr, 0, sizeof(adr));

adr.sin_family=AF_INET;
adr.sin_port = htons(atoi(argv[2]));
adr.sin_addr.s_addr = htonl(INADDR_ANY);

if(bind(recv-sock, (struct sockaddr*)&adr, sizeof(adr))==-1)
	error_handling("bind() error");
while(1)
{
	str_len = recvfrom(recv_sock, buf, BUF_SIZE-1, 0, NULL, 0);
    if(str_len <0)
    	break;
    buf[str_len]=0;
    fputs(buf, stdout);
}

BELATED ARTICLES

more