(English is not my native language, do not worry if some sentences are strange;)).
I developed a PONG game and, by the way, created several classes to help me manage the window, the event ... and the network , because I added a LAN , but for now you have to enter the address of the person you want to play with. And the solution for this was broadcast (LAN scan for the player) . It was easy with ipv4, just use the address 255.255.255.255, but we are in 2017 and provide a function that works only with ipv4 sucks ...
Then I look for a way to broadcast from ipv6, and I learn about multi-casting, but this part just lost me. = (
I use standard libraries for Linux in C ++ , I found some examples of multi-throw that did not work with me. The best I did at this time was sending the udp package from one instance of the program to another on the same computer.
How can I use multi-cast with ipv6 udp socket on Linux in C / C ++?
The best code found on the Internet (I rebuilt it) that almost works (client and service are all in one, the choice is made by adding 1 or 0 to argv):
int main(int argc, char const *argv[]) {
struct sockaddr_in6 groupSock;
int sd = -1;
char databuf[10];
int datalen = sizeof databuf;
if((sd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
perror("Opening datagram socket error");
return 1;
} else {
cout << "Opening the datagram socket...OK." << endl;;
}
int reuse = 1;
if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof reuse) < 0) {
perror("Setting SO_REUSEADDR error");
close(sd);
return 1;
} else {
cout << "Setting SO_REUSEADDR...OK." << endl;
}
memset((char *) &groupSock, 0, sizeof groupSock);
groupSock.sin6_family = AF_INET6;
inet_pton(AF_INET6, "ff0e::/16", &groupSock.sin6_addr);
groupSock.sin6_port = htons(4321);
int ifindex = if_nametoindex ("enp3s0");
cout << "ifindex is " << ifindex << endl;
if(setsockopt(sd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof ifindex)) {
perror("Setting local interface error");
return 1;
} else {
cout << "Setting the local interface...OK" << endl;
}
int choice;
if (argc < 2) {
cout << "missing argv[1]" << endl;
return 1;
}
sscanf (argv[1], "%d", &choice);
if (choice == 0) {
memset(databuf, 'a', datalen);
databuf[sizeof databuf - 1] = '\0';
if (sendto(sd, databuf, datalen, 0, (sockaddr*)&groupSock, sizeof groupSock) < 0) {
cout << "Error in send" << endl;
} else {
cout << "Send okay!" << endl;
}
}
else if (choice == 1) {
groupSock.sin6_addr = in6addr_any;
if(bind(sd, (sockaddr*)&groupSock, sizeof groupSock)) {
perror("Binding datagram socket error");
close(sd);
return 1;
} else {
cout << "Binding datagram socket...OK." << endl;
}
struct ipv6_mreq group;
inet_pton (AF_INET6, "ff0e::", &group.ipv6mr_multiaddr.s6_addr);
group.ipv6mr_interface = ifindex;
if(setsockopt(sd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&group, sizeof group) < 0) {
perror("Adding multicast group error");
close(sd);
return 1;
} else {
cout << "Adding multicast group...OK." << endl;
}
if (read(sd, databuf, datalen) < 0) {
perror("Error in read");
} else {
databuf[sizeof databuf - 1] = '\0';
cout << "Read Okay" << endl;
cout << "Message is : " << databuf << endl;
}
}
return 0;
}
Here the address is ff0e :: but I tried ff01 :: and ff02 ::.
I need help, I did not find simple documentation about this. Thanks in advance for any response.
Edit: Thanks to Ron Maupin and Jeremy Friesner for these comments, this helps me.
:
! ff12:: blah: blah (...) ff0e:: works! , ?