私は、Linuxでのマルチキャストパケットストリームを処理しよう。266sのために - 278s(それは常に正確に同じ時間帯ではありません)受信には罰金を動作しますが、その後、何のパケットは、もはや受信されません。
これは私がマルチキャストを初期化する方法です。
int arg = 1;
int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(fd == -1) {
fprintf(stderr, "Error creating socket, %s\n", strerror(errno));
return;
}
if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0) {
fprintf(stderr, "Failed to set `SO_REUSEADDR`, %s\n", strerror(errno));
return;
}
fcntl(fd, F_SETFL, O_NONBLOCK);
static struct ifreq intf;
strncpy(intf.ifr_name, cfg->ifname_buf, IF_NAMESIZE);
if(setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (char*)&intf, sizeof(intf)) < 0) {
fprintf(stderr, "Failed to set `SO_BINDTODEVICE`, %s\n", strerror(errno));
return;
}
struct sockaddr_in sin;
memset(&sin, 0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = htons(xxxxx);
sin.sin_addr.s_addr = inet_addr("xxx.xxx.xxx.xxx");
if(bind(fd, (struct sockaddr*)&sin, sizeof(struct sockaddr)) < 0) {
fprintf(stderr, "Error on binding socket, %s\n", strerror(errno));
return;
}
ioctl(fd, SIOCGIFADDR, &intf);
struct ip_mreqn igmpv2_req;
memset(&igmpv2_req, 0, sizeof(struct ip_mreqn));
if(inet_pton(AF_INET, "xxx.xxx.xxx.xxx", &igmpv2_req.imr_multiaddr.s_addr)) {
memcpy(&igmpv2_req.imr_address, &cfg->ifaddr.sin_addr, sizeof(struct in_addr));
igmpv2_req.imr_ifindex = cfg->ifindex;
printf("Multiaddr: %s\n", inet_ntoa(igmpv2_req.imr_multiaddr));
printf("Interfaceaddr: %s\n", inet_ntoa(igmpv2_req.imr_address));
printf("Ifindex: %d\n", igmpv2_req.imr_ifindex);
if(setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &igmpv2_req, sizeof(struct ip_mreqn)) < 0) {
fprintf(stderr, "Failed to set `IP_ADD_MEMBERSHIP`: %s\n", strerror(errno));
return;
} else {
printf("Saved FD for igmp socket!\n");
cfg->socket_fd_igmp = fd;
}
} else {
fprintf(stderr, "Failed `inet_pton` igmp-multiaddr, %s\n", strerror(errno));
return;
}
280S - 私が言ったように、それは266の罰金に動作します。その後、何のパケットが受信されません。道の私は、マルチキャストグループにインターフェイスを追加したり、理由はいくつかのカーネルキューがいっぱいであることの(私は毎秒20万個のパケットまで受信)ためであるかどうかはわかりません。
マルチキャストは些細なものではありません。あなたが記述しているものから、次の処理が行われます。
あなたが実行するとき
setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &igmpv2_req, sizeof(struct ip_mreqn))
その後、クライアントは、IGMPこのグループの参加メッセージを送信します。あなたのスイッチはいIGMPスヌーピングが有効になっており、今、あなたのホストのポートにこのグループのマルチキャストパケットを転送するために知っています。
さて、あなたは観察時間後(4〜5分、260秒は確かに多くのスイッチでデフォルトです)この情報は、スイッチ時間のうち、ため、ホストは、定期的にこれらのメッセージを送信しない/未承諾。
あなたは必要とするマルチキャストルータ定期的で応答したホスト、照会することを、ネットワーク上のIGMPレポート最新のスイッチングハードウェア上のテーブルをIGMPスヌーピングを保つために、彼らが聞いているマルチキャストグループのために、。
また、あなたもそうすることを、マルチキャスト送信者と受信者との間のすべてのデバイス上でスヌーピングをディセーブルIGMPに試すことができ、すべてのマルチキャストメッセージがにフラッディングされ、すべてのポート(ビューのレイヤ2ポイントからそれらの放送を行います)。第一の方法が好適であるので、これは、レイヤ2セグメントに非常に高い負荷をかけることができます。
醜い回避策は、(私はまだテストしていないこと)でメンバーシップを削除し、再度追加することができsetsockopt()
、すべての2-3分。これは、IGMPパケットを強制するため、マルチキャストの接続性を維持するが、これはそれが仕事になっているかではないはずです。