新千葉 ガーベージ・コレクション

FPGA マガジンやインターフェースで書けなかったこと等をちょぼちょぼ書いてます。@ryos36

似非 RTP とマルチキャスト

苦労するぜ。結局こんな感じになった。

#define IP_ADDR "239.192.0.1"
                        InetAddress multicast(IP_ADDR);
                        uint32_t ip_addr;
                        ip_addr = multicast.ip_addr;

                        struct ip_mreq maddr;
                        memset(&maddr, 0, sizeof(maddr));
                        maddr.imr_multiaddr.s_addr = ip_addr;
                        maddr.imr_interface.s_addr = INADDR_ANY;

                        int udp_fds;
                        udp_fds = udp.getDatagram();
                        if ( setsockopt(udp_fds, IPPROTO_IP, IP_ADD_MEMBERSHIP, &maddr, sizeof(maddr)) != 0 ) {
                                perror(IP_ADDR);
                                exit(123);
                        }

InetAddress と udp は自分で作ったクラス。重要なのは setsockopt だ。bind は この後でも後ろでもいいみたい。bind で同じマルチキャストのグループで同じポートの受信が一つのシステム(PC)内で出来たと記憶していたのだが、、、今やって見ると出来ない。そういうものか?
C# でも作ってみた。

            udp = new UdpClient(port_no);
            udp.JoinMulticastGroup(IPAddress.Parse("239.192.0." + (1 + vid)), TIME_TO_LIVE_50); 

            ....
            ....
            udp.DropMulticastGroup((IPAddress.Parse("239.192.0." + (1 + vid))));


            ....
            ....
            udp.Close();

Close をすぐするなら DropMulticastGroup はいらない。参考までに書くと JoinMulticastGroup をするとドライバを通してハードウェアにマルチキャストアドレスが登録される。これにより、ハードレベルで該当するマルチキャストアドレスを受信しソフト(OSへ)にあげるようになる。JoinMulticastGroup しないとそもそもハードウェアが受信してくれない。ハードウェア側ではマルチキャストアドレスを記録する数が決まっているので、ある数以上 JoinMulticastGroup すると全てのマルチキャストアドレスを拾うことになる。

送信側は簡単。普通の UDP 送信で送信先にマルチキャストアドレスを使えばいいだけ。