gpt4 book ai didi

c - 无法使用 IPv6 进行多播

转载 作者:太空宇宙 更新时间:2023-11-04 08:22:55 24 4
gpt4 key购买 nike

这是发送方和接收方的代码(组合)。

int main (int argc, char *argv[]) {
struct in6_addr localInterface;
struct sockaddr_in6 groupSock;
// socket descriptor for multicast
int sd;

char databuf[10];
// length of message
int datalen = sizeof(databuf);

/* Create a datagram socket on which to send/receive. */
sd = socket(AF_INET6, SOCK_DGRAM, 0);

if(sd < 0) {
perror("Opening datagram socket error");
exit(1);
}
else {
printf("Opening the datagram socket...OK.\n");
}

/* Enable SO_REUSEADDR to allow multiple instances of this */
/* application to receive copies of the multicast datagrams. */
{
int reuse = 1;
if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0)
{
perror("Setting SO_REUSEADDR error");
close(sd);
exit(1);
}

else {
printf("Setting SO_REUSEADDR...OK.\n");
}
}

/* Initialize the group sockaddr structure with a */
memset((char *) &groupSock, 0, sizeof(groupSock));
groupSock.sin6_family = AF_INET6;
// address of the group
// groupSock.sin6_addr = inet6_addr("ff5e::/16");
inet_pton(AF_INET6, "ff5e::/16", &(groupSock.sin6_addr));

groupSock.sin6_port = htons(4321);

/* Set local interface for outbound multicast datagrams. */
/* The IP address specified must be associated with a local, */
/* multicast capable interface. */
char *ip_address = argv[2];
inet_pton (AF_INET6, ip_address, &(localInterface.s6_addr));

memset((char *) &localInterface, 0, sizeof(localInterface));

int ifindex;
ifindex = if_nametoindex ("eth5");
printf ("ifindex is %d\n", ifindex);

if(setsockopt(sd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)))
{
perror("Setting local interface error");
exit(1);
}
else {
printf("Setting the local interface...OK\n");
}

// choice is 0 for sending and 1 for receiving
int choice;
sscanf (argv[1], "%d", &choice);

// if sending
if (choice == 0) {
int i;
for (i = 0; i < datalen-1; ++i) {
databuf[i] = 'a';
}
databuf[i] = 0;

if (sendto(sd, databuf, datalen, 0, (struct sockaddr*)&groupSock, sizeof(groupSock)) < 0) {
printf ("Error in send\n");
}

else {
printf ("Send okay!\n");
}
}

// if receiving
else if (choice == 1) {
groupSock.sin6_addr = in6addr_any;
if(bind(sd, (struct sockaddr*)&groupSock, sizeof(groupSock))) {
perror("Binding datagram socket error");
close(sd);
exit(1);
}

else {
printf("Binding datagram socket...OK.\n");
}

/* Join the multicast group ff5e::/16 on the local */
/* interface. Note that this IP_ADD_MEMBERSHIP option must be */
/* called for each local interface over which the multicast */
/* datagrams are to be received. */
struct ipv6_mreq group;
inet_pton (AF_INET6, "ff5e::", &(group.ipv6mr_multiaddr.s6_addr));

// group.imr_interface.s6_addr = inet_addr(ip_address);
group.ipv6mr_interface = ifindex;

if(setsockopt(sd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0) {
perror("Adding multicast group error");
close(sd);
exit(1);
}

else {
printf("Adding multicast group...OK.\n");
}

if (read(sd, databuf, datalen) < 0) {
perror("Error in read");
}

else {
printf("Read Okay\n");
printf ("Message is : %s\n", databuf);
}
}

}

如果发送者和接收者在不同的节点上,接收者不会收到消息(我已使用 ping6 检查它们是否已连接)。我正在使用 Linux Ubuntu 14.04。使用 tcpdump 捕获 ipv6 数据包显示数据包未在发送方发送。有什么问题?

最佳答案

一个问题是您选择的 IPv6 多播地址不当。 FF5E:: 分解如下:

  • FF 表示是组播。
  • 5 是标志集 (0101),此值是一组无效的标志。设置最高位意味着您有一个嵌入式 RP 地址,而您显然没有。为此,标志集必须为 7 (0111),然后遵循嵌入 RP 地址的所有规则。
  • E 表示它是全局范围。

这个多播地址应该正确地丢弃在它遇到路由器的任何路径中。

请参阅 RFC 4291、3306 和 3956 以创建 IPv6 多播地址,包括标志和范围的含义。

关于c - 无法使用 IPv6 进行多播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32598293/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com