행복한 하루
Raspberry Pi4를 이용한 멀티캐스트 송신 코드 및 테스트 (Multicast Sender) 본문
안녕하세요.
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 문자열을 포함한 패킷을 확인할 수 있습니다.
다음에는 수신부를 확인해보겠습니다.
감사합니다.
<참고 사이트>
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 [인터페이스]
'RaspberryPi' 카테고리의 다른 글
Raspberry Pi에서 MariaDB Docker Container 와 Python 연동하기 (Docker-compose 사용) (0) | 2023.04.06 |
---|---|
Raspberry Pi에 Docker로 MariaDB 설치하기 (0) | 2023.03.31 |
Quest4-Pico W - 최종 결과물 완성 (상세 설명 및 동작 영상-화재감지기) (0) | 2022.10.23 |
Quest3-Pico W - 클라우드 연결 및 데이터 업로드(화재감지기) (0) | 2022.09.22 |
[도서 실습] Qt 5 and OpenCV 4 Computer Vision (Raspberry Pi CM 4 – ImageEditor) (0) | 2022.06.18 |