안녕하세요.
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 [인터페이스]
'Embedded > RaspberryPI' 카테고리의 다른 글
Raspberry PI 4(CM4 Module)과 IO보드(MCUZONE Tiny, waveshare CM4-IO-BASE-B)에서 파이캠(OV5647) 카메라 동작 시키기 (3) | 2024.10.15 |
---|---|
Raspberry Pi 4 CM4 EDA 방열판(heatsink, Cooler) 확인하기 (2) | 2024.10.10 |
Raspberry pi CM4(Bullseye)에서 Tesseract 4.1.3 설치 및 OCR 테스트 (0) | 2024.05.28 |
W5100S-EVB-Pico를 이용해서 MQTT 발행(Publish) 해보기 (0) | 2024.02.02 |
Raspberry Pi 4(Bookworm)에서 WiringPi 설치해서 사용하기 (2) | 2024.01.22 |