3

マルチキャストパケットを送受信する小さなプログラムを書いています。送信インターフェイスをアドレスではなく名前(例:eth0)で設定する必要があります。したがって、(struct in_addrではなく)struct ip_mreqnを使用して、そのimr_ifindexフィールドを使用してインターフェイスインデックス(インターフェイスの名前を使用して取得できます)を設定できるようにする必要があります。

ただし、何らかの理由で機能しません。setsockopt()の呼び出しは正常に機能しますが、次のsendto()の呼び出しは「無効な引数」エラーを返します。もちろん、ip_mreqnをin_addrに置き換えて、代わりにインターフェイスのアドレスを使用すると、エラーは消えます。

以下は私のコードです:

sd = socket(AF_INET, SOCK_DGRAM, 0);

struct ip_mreqn addr;
addr.imr_ifindex = if_nametoindex("eth0");
setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr);

struct sockaddr_in sock_addr;
memset((char *) &sock_addr, 0, sizeof(sock_addr));
sock_addr.sin_family = AF_INET;
sock_addr.sin_port = destination_port;
sock_addr.sin_addr.s_addr = destination_address;

char msg[] = "abc";

while (sendto(sd, msg, sizeof(msg), 0, reinterpret_cast<const sockaddr*>(&sock_addr),
  sizeof(sock_addr)) < 0)
    throw std::runtime_error(strerror(errno));

IP_MULTICAST_IFを設定するときにstructip_mreqnを使用することに問題はありますか?誰かが何か考えを持っていますか?本当に助けに感謝します。ありがとう。

宛先ポートとアドレスはすでにネットワークバイトオーダーになっていることに注意してください。

4

2 に答える 2

4

tldp のマルチキャスト ハウツーから:

通常、システム管理者は、マルチキャスト データグラムの送信元となるデフォルト インターフェイスを指定します。プログラマーは、このオプションを使用して、これをオーバーライドし、特定のソケットの具体的な発信インターフェイスを選択できます。

struct in_addr interface_addr;
setsockopt (socket, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr));

それらによると、インターフェースへのインデックスだけでは十分ではありません。

編集:
と 混同IP_MULTICAST_IFしている可能性があります。IPV6_MULTICAST_IF後者は、インターフェイス番号を示すために符号なし整数を取ります ( を参照man 7 ipv6)。

編集:
与えられた例は期待どおりに機能することが判明しました。これが私の完全なテストケースです:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/socket.h>


int main()
{
    int sd = socket(AF_INET, SOCK_DGRAM, 0);
    struct sockaddr_in sa = {0};
    struct ip_mreqn addr = {{0}};
    char msg[] = "abc";

    addr.imr_ifindex = if_nametoindex("eth0");
    setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr));

    sa.sin_family = AF_INET;
    sa.sin_port = 8653;

    inet_pton(AF_INET, "224.255.255.5", &sa.sin_addr);
    if (sendto(sd, msg, sizeof(msg), 0, (void*)&sa, sizeof(sa)) < 0) {
        perror("bugger");
        return 1;
    }
    return 0;
}
于 2012-06-12T11:34:49.943 に答える