Embedded/RaspberryPI

Raspberry Pi4를 이용한 멀티캐스트 송신 코드 및 테스트 (Multicast Sender)

변화의 물결1 2024. 7. 5. 00:04

 

 

안녕하세요.

 

 IPTV나 네트워크 쪽으로 통신 프로그램할 경우가 아니면 주로 사용하는 방식은 아니지만 이번에 확인할 일이 있어서 찾아본 내용 공유드립니다. 송신부는 C 프로그램으로 테스트하였고, 다음 내용에 올릴 수신부는 Qt 소스 공개된 것이 있어서 PC에서 수정해서 테스트해 보았습니다.


 

1. 멀티캐스트 간단한 개념

 

  컴퓨터 네트워크에서 멀티캐스트(multicast)란 한 번의 송신으로 메시지나 정보를 목표한 여러 컴퓨터에 동시에 전송하는 것을 말한다. 이때 망 접속 형태가 요구할 경우에 한해, 자동으로 라우터와 같은 다른 네트워크 요소들에 메시지의 복사본이 생성된다.

 

  멀티캐스트는 보통 IP 멀티캐스트 형태로 구현되는데, 이는 스트리밍을 위한 인터넷 프로토콜 응용 프로그램(Internet Protocol application) 및 인터넷 텔레비전에서 주로 사용된다. IP 멀티캐스트에서 멀티캐스트는 주로 IP 라우팅 단계에서 구현되며, 이때 라우터는 데이터그램을 멀티캐스트 대상 주소로 보내기 위한 최적의 전송 경로를 생성한다.

 

  다른 캐스팅과 비교해서 보면 개념적으로 조금 쉽게 알 수 있습니다. 이것보다 조금 더 상세한 내용은 한단 링크를 참조하시면 도움이 될 것입니다.

 

 

 

<WIKI-멀티캐스트 자료>

 

 

2. 라즈베리안 OS에서 멀티캐스팅 확인하는 방법

 

  라즈베리파이에 OS가 설치가 되어 있다면 기본적으로 Multicast가 설정되어 있지 않을까 합니다. 그렇지만 Multicast설정이 되어 있는지 확인합니다. 아래와 같이 명령어를 입력하면 MULTICAST라고 나타납니다. 

 

pi@raspberrypi:~ $ ifconfig

 

 

 

 pi@raspberrypi:~ $ ip  a

 

 

 

3. 멀티캐스트를 설정하는 방법

 

  만약 MULTICAST가 표시되지 않는다면 활성화시킵니다.

 

pi@raspberrypi:~ $ sudo ifconfig eth0 multicast

 

 

  multicast 설정을 취소하려면 “-“를 추가해 주면 됩니다.

 

pi@raspberrypi:~ $ sudo ifconfig eth0 -multicast

 

 

 

 

4. Sender 소스  작성

 

  우선 vim mCast.c로 해서 파일을 만듭니다.

  기본적으로 socket 통신과 유사한 형태를 가지므로 소켓과 ip주소를 위한 구조체를 선언합니다. 그리고 멀티캐스트를 위한 주소를 지정합니다.  그리고 멀티캐스트와 별도로 자신의 IP주소를 입력합니다.

 

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main (int argc, char* argv[])
{
    int sockfd, send_len;
    struct sockaddr_in multicast_addr;      
    struct in_addr     local_addr;
    char* pMsg;

    // Max Router Num
    char ttl=5;

    // multicast addr
    char *multicast_ip = "225.192.0.10";
    int   multicast_port  = 50000;

    // send device ip address [current computer]
    char *local_ip      = "192.168.0.133";

    // generatae socket
    sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    if (sockfd < 0)
    {
        printf("Socket open error\n");
        return -1;
    }

    // setting multicast address
    multicast_addr.sin_family      = AF_INET;
    multicast_addr.sin_addr.s_addr = inet_addr(multicast_ip);
    multicast_addr.sin_port        = htons(multicast_port);

  

 

 - 저장된 메시지를 사용하지 않고 실행 시 입력한 문자열을 보내기 위해서 메모리 할당시켜 문자열을 저장합니다.

 

// sending message
    char *send_message ="Hello multicast";

    pMsg = malloc(sizeof(char) * 20);
    memcpy(pMsg, argv[1], strlen(argv[1]));

 

 

- setsockopt() 함수로 TTL(패킷을 얼마나 멀리 전달할지 결정하는 요소)을 설정합니다.

 

// set the maximum number of routers.
    if(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL,(void *)&ttl,sizeof(ttl))<0)
    {
        printf("Socket setsockopt error.[ttl]\n");

        close(sockfd);
        return -1;
    }

 

 

- 기존에 설정된 네트워크 설정을 무시하고 현재 프로그래머가 설정한 네트워크 인터페이스(IP_MULTICAT_IF)를 선택하게 설정합니다.

 

// set the Ip address to be transmitted(local ip)
    local_addr.s_addr = inet_addr(local_ip);   
    if(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF,(char *)&local_addr, sizeof(local_addr))<0)
    {
        printf("Socket setsockopt error.[Interface]\n");

        close(sockfd);
        return -1;
    }

 

 

- 실행 시 같이 입력한 문자열의 길이를 계산한 후 멀티캐스트로 보냅니다. 그리고 사용한 리소스는 해제합니다.

 

    // send message
    send_len = sendto(sockfd, pMsg, strlen(pMsg), 0, (struct sockaddr*)&multicast_addr, sizeof(multicast_addr));

    //send_len = sendto(sockfd, send_message, strlen(send_message), 0, (struct sockaddr*)&multicast_addr, sizeof(multicast_addr));
    printf("send len : %d\n",send_len);
    if( send_len < 0 )
    {
        printf("Sending multicast message error");
    }
    else
        printf("Sending multicast message...Success\n");

    free(pMsg);
    close(sockfd);
    return 0;
}

 

 

5. 컴파일 방법

 

  이상 없이 컴파일이 실행되면 mcast 파일일 생성됩니다.

 

 pi@raspberrypi:~ $ gcc -o mcast mCast.c

 

 

 

 

6.  실행 및 결과 확인

 

 pi@raspberrypi:~ $ ./mcast FirstMessage

 

 

 

 

  Wireshark로 전달되는 패킷을 확인해 봅니다. 그러면 FirstMessage 문자열을 포함한 패킷을 확인할 수 있습니다.

 

 

  

다음에는 수신부를 확인해 보겠습니다. (Qt 강좌에 작성 예정)

 

감사합니다.

  

 

<참고 사이트>

1. [Linux/C언어] 멀티캐스트 송신 코드 및 테스트 (Multicast Sender)

https://softtone-someday.tistory.com/16

2. Can't receive UDP Multicast packets

https://raspberrypi.stackexchange.com/questions/111201/cant-receive-udp-multicast-packets

https://ansan-survivor.tistory.com/1295

https://blockdmask.tistory.com/442

https://blockdmask.tistory.com/381

3. 멀티캐스트

https://ko.wikipedia.org/wiki/%EB%A9%80%ED%8B%B0%EC%BA%90%EC%8A%A4%ED%8A%B8

4. IP MultiCast 일반

https://www.joinc.co.kr/w/Site/Network_Programing/Documents/MultiCast

5. 멀티캐스트( Multicast )

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=kirayamato4&logNo=220779462804

6. 멀티캐스트 프로그래밍

https://wiki.kldp.org/HOWTO/html/Multicast/Multicast-HOWTO-6.html

7. 와이어샤크(Wireshark) 사용법 #2 [인터페이스]

https://citizen.tistory.com/6  

 

mCast.c
0.00MB

 

반응형