Hello Tina,
Thanks for the reply and understands the theory but unable to make it in my
code.
Here is my server and client code, both can be compiled as a console app in
windows.And run as
multicast_server 224.0.22.1 9210 HelloIPv4World
multicast_server ff15::1 2001 HelloIPv6World
multicast_client 224.0.22.1 9210
multicast_client ff15::1 2001
For the sample code if the server runs as IPV6 (multicast_server ff15::1 2001
HelloIPv6World) then cleint running in IPV6 (multicast_client ff15::1 2001)
receives the multicast message.But the client running in IPV4 does not receive
the multicast message.
I want to run the server so that both IPV4 and IPV6 client can receive the
multicast messages.How to do that ,some C/C++ code sample will be great.
Thanks
Ghanashyam
// server.cpp : Defines the entry point for the console application.
//
/* multicast_server.c
* This sample demonstrates a Windows multicast server that works with either
* IPv4 or IPv6, depending on the multicast address given.
* Requires Windows XP+/Use MSVC and platform SDK to compile.
* Troubleshoot: Make sure you have the IPv6 stack installed by running
* >ipv6 install
*
* Usage:
* multicast_server multicastip port data [ttl]
*
* Examples:
* >multicast_server 224.0.22.1 9210 HelloIPv4World
* >multicast_server ff15::1 2001 HelloIPv6World
*
#include <stdio.h> /* for fprintf() */
#include <winsock2.h> /* for socket(), connect(), send(), and recv() */
#include <ws2tcpip.h> /* for ip options */
#include <stdlib.h> /* for atoi() and exit() */
#if defined(_MSC_VER)
#pragma comment(lib, "ws2_32.lib")
#endif
static void DieWithError(char* errorMessage)
{
fprintf(stderr, "%s\n", errorMessage);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
SOCKET sock; /* Socket */
WSADATA wsaData; /* For WSAStartup */
char* multicastIP; /* Arg: IP Multicast address */
char* multicastPort; /* Arg: Server port */
char* sendString; /* Arg: String to multicast */
size_t sendStringLen; /* Length of string to multicast */
DWORD multicastTTL; /* Arg: TTL of multicast packets */
ADDRINFO* multicastAddr; /* Multicast address */
ADDRINFO hints = { 0 }; /* Hints for name lookup */
if ( WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
DieWithError("WSAStartup() failed");
}
if ( argc < 4 || argc > 5 )
{
fprintf(stderr, "Usage: %s <Multicast Address> <Port> <Send String>
[<TTL>]\n", argv[0]);
exit(EXIT_FAILURE);
}
multicastIP = argv[1]; /* First arg: multicast IP address */
multicastPort = argv[2]; /* Second arg: multicast port */
sendString = argv[3]; /* Third arg: String to multicast */
multicastTTL = (argc == 5 ? /* Fourth arg: If supplied, use
command-line */
atoi(argv[4]) : 1); /* specified TTL, else use default TTL
of 1 */
sendStringLen = strlen(sendString); /* Find length of sendString */
/* Resolve destination address for multicast datagrams */
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST;
if ( getaddrinfo(multicastIP, multicastPort, &hints, &multicastAddr) != 0 )
{
DieWithError("getaddrinfo() failed");
}
printf("Using %s\n", multicastAddr->ai_family == PF_INET6 ? "IPv6" :
"IPv4");
/* Create socket for sending multicast datagrams */
if ( (sock = socket(multicastAddr->ai_family, multicastAddr->ai_socktype,
0)) == INVALID_SOCKET )
{
DieWithError("socket() failed");
}
/* Set TTL of multicast packet */
if ( setsockopt(sock,
multicastAddr->ai_family == PF_INET6 ? IPPROTO_IPV6
: IPPROTO_IP,
multicastAddr->ai_family == PF_INET6 ? IPV6_MULTICAST_HOPS
: IP_MULTICAST_TTL,
(char*) &multicastTTL, sizeof(multicastTTL)) != 0 )
{
DieWithError("setsockopt() failed");
}
for (;;) /* Run forever */
{
if ( sendto(sock, sendString, sendStringLen, 0,
multicastAddr->ai_addr, multicastAddr->ai_addrlen) !=
sendStringLen )
{
DieWithError("sendto() sent a different number of bytes than
expected");
}
Sleep(3000); /* Multicast sendString in datagram to clients every 3
seconds */
}
/* NOT REACHED */
freeaddrinfo(multicastAddr);
closesocket(sock);
return 0;
}
// client.cpp : Defines the entry point for the console application.
//
/* multicast_client.c
* This sample demonstrates a Windows multicast client that works with either
* IPv4 or IPv6, depending on the multicast address given.
* Requires Windows XP+/Use MSVC and platform SDK to compile.
* Troubleshoot: Make sure you have the IPv6 stack installed by running
* >ipv6 install
*
* Usage:
* multicast_client multicastip port
*
* Examples:
* >multicast_client 224.0.22.1 9210
* >multicast_client ff15::1 2001
*
#include <stdio.h> /* for printf() and fprintf() */
#include <winsock2.h> /* for socket(), connect(), sendto(), and recvfrom() */
#include <ws2tcpip.h> /* for ip_mreq */
#include <stdlib.h> /* for atoi() and exit() */
#include <string.h> /* for memset() */
#include <time.h> /* for timestamps */
#if defined(_MSC_VER)
#pragma comment(lib, "ws2_32.lib")
#endif
void DieWithError(char* errorMessage)
{
fprintf(stderr, "%s\n", errorMessage);
exit(EXIT_FAILURE);
}
int main(int argc, char* argv[])
{
SOCKET sock; /* Socket */
WSADATA wsaData; /* For WSAStartup */
char* multicastIP; /* Arg: IP Multicast Address */
char* multicastPort; /* Arg: Port */
ADDRINFO* multicastAddr; /* Multicast Address */
ADDRINFO* localAddr; /* Local address to bind to */
ADDRINFO hints = { 0 }; /* Hints for name lookup */
if ( WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
DieWithError("WSAStartup() failed");
}
if ( argc != 3 )
{
fprintf(stderr,"Usage: %s <Multicast IP> <Multicast Port>\n", argv[0]);
exit(EXIT_FAILURE);
}
multicastIP = argv[1]; /* First arg: Multicast IP address */
multicastPort = argv[2]; /* Second arg: Multicast port */
/* Resolve the multicast group address */ hints.ai_family = PF_UNSPEC;
hints.ai_flags = AI_NUMERICHOST; if ( getaddrinfo(multicastIP, NULL, &hints,
&multicastAddr) != 0 ) { DieWithError("getaddrinfo() failed"); } printf("Using
%s\n", multicastAddr->ai_family == PF_INET6 ? "IPv6" : "IPv4"); /* Get a local
address with the same family (IPv4 or IPv6) as our multicast group */
hints.ai_family = multicastAddr->ai_family;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_PASSIVE; /* Return an address we can bind to */
if ( getaddrinfo(NULL, multicastPort, &hints, &localAddr) != 0 )
{
DieWithError("getaddrinfo() failed");
}
/* Create socket for receiving datagrams */
if ( (sock = socket(localAddr->ai_family, localAddr->ai_socktype, 0)) ==
INVALID_SOCKET )
{
DieWithError("socket() failed");
}
/* Bind to the multicast port */
if ( bind(sock, localAddr->ai_addr, localAddr->ai_addrlen) != 0 )
{
DieWithError("bind() failed");
}
/* Join the multicast group. We do this seperately depending on whether we
* are using IPv4 or IPv6. WSAJoinLeaf is supposed to be IP version agnostic
* but it looks more complex than just duplicating the required code. */
if ( multicastAddr->ai_family == PF_INET &&
multicastAddr->ai_addrlen == sizeof(struct sockaddr_in) ) /* IPv4 */
{
struct ip_mreq multicastRequest; /* Multicast address join structure */
/* Specify the multicast group */
memcpy(&multicastRequest.imr_multiaddr,
&((struct sockaddr_in*)(multicastAddr->ai_addr))->sin_addr,
sizeof(multicastRequest.imr_multiaddr));
/* Accept multicast from any interface */
multicastRequest.imr_interface.s_addr = htonl(INADDR_ANY);
/* Join the multicast address */
if ( setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)
&multicastRequest, sizeof(multicastRequest)) != 0 )
{
DieWithError("setsockopt() failed");
}
}
else if ( multicastAddr->ai_family == PF_INET6 &&
multicastAddr->ai_addrlen == sizeof(struct sockaddr_in6) ) /*
IPv6 */
{
struct ipv6_mreq multicastRequest; /* Multicast address join structure
*/
/* Specify the multicast group */
memcpy(&multicastRequest.ipv6mr_multiaddr,
&((struct sockaddr_in6*)(multicastAddr->ai_addr))->sin6_addr,
sizeof(multicastRequest.ipv6mr_multiaddr));
/* Accept multicast from any interface */
multicastRequest.ipv6mr_interface = 0;
/* Join the multicast address */
if ( setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char*)
&multicastRequest, sizeof(multicastRequest)) != 0 )
{
DieWithError("setsockopt() failed");
}
}
else
{
DieWithError("Neither IPv4 or IPv6");
}
freeaddrinfo(localAddr);
freeaddrinfo(multicastAddr);
for (;;) /* Run forever */
{
time_t timer;
char recvString[500]; /* Buffer for received string */
int recvStringLen; /* Length of received string */
/* Receive a single datagram from the server */
if ( (recvStringLen = recvfrom(sock, recvString, sizeof(recvString) -
1, 0, NULL, 0)) < 0 )
{
DieWithError("recvfrom() failed");
}
recvString[recvStringLen] = '\0';
/* Print the received string */
time(&timer); /* get time stamp to print with recieved data */
printf("Time Received: %.*s : %s\n", strlen(ctime(&timer)) - 1,
ctime(&timer), recvString);
}
/* NOT REACHED */
closesocket(sock);
exit(EXIT_SUCCESS);
}
From: Tina TSOU <tina.tsou.zout...@huawei.com>
To: Ghanashyam Satpathy <ghanashyam_satpa...@yahoo.com>; "ipv6@ietf.org"
<ipv6@ietf.org>
Cc: "multr...@ietf.org" <multr...@ietf.org>; MBONED WG <mbo...@ietf.org>
Sent: Tuesday, December 20, 2011 6:09 AM
Subject: RE: Question on IPV4/IPV6 Multicast interoperability
Ghanashyam,
http://datatracker.ietf.org/doc/draft-tsou-multrans-addr-acquisition/
http://datatracker.ietf.org/doc/draft-zhou-multrans-af1-specification/
Running code exists.
Hope it helps.
Best Regards,
Tina TSOU
http://tinatsou.weebly.com/contact.html
From:ipv6-boun...@ietf.org [mailto:ipv6-boun...@ietf.org] On Behalf Of
Ghanashyam Satpathy
Sent: Sunday, December 18, 2011 3:14 AM
To: ipv6@ietf.org
Subject: Question on IPV4/IPV6 Multicast interoperability
Hello,
I have a question on IPV4/IPV6 Multicast interoperability. We have succesfully
upgraded our application(Windows Based) to support IPV6 and faced issue on
multicast interoperability. Multicast messages sent by a IPV6 server is
successfully receved by a client running on IPV6. But any client running on
IPV4 is not able to receive the message.
Quite a no. of things I tried like using IPV4 mapped IPV6 address and V4
embeded V6 adress.But nothing seems to be working.Would like to know an unified
way so that one multicast message sent by an IPV6 server should be received by
both V6 and V4 client.
Would be great if somebody can send some code snippet(C/C++) on it.
Thanks.
Ghanashyam
--------------------------------------------------------------------
IETF IPv6 working group mailing list
ipv6@ietf.org
Administrative Requests: https://www.ietf.org/mailman/listinfo/ipv6
--------------------------------------------------------------------