186 lines
4.9 KiB
C++
186 lines
4.9 KiB
C++
#include <common/windows.hpp>
|
|
#include <common/array.hpp>
|
|
#include <common/systime.hpp>
|
|
#include <socket/socket.hpp>
|
|
#include <socket/sockaddr.hpp>
|
|
#include <socket/ipmcast.hpp>
|
|
#include <socket/wsadata.hpp>
|
|
#include <iostream.h>
|
|
|
|
void outDebug(const String &string);
|
|
void mcastsnd(int destPort,String destIP,Array<BYTE> &message,int frequency,int ttl=1);
|
|
void mcastrcv(int destPort,String rcvIPAddress,int ttl=1);
|
|
|
|
void main(int argc,char **argv)
|
|
{
|
|
String strOp;
|
|
String strIPAddress;
|
|
String strPort;
|
|
String strData;
|
|
String strFrequency="1000";
|
|
Array<BYTE> message;
|
|
|
|
outDebug("MCAST 1.00 - Sean Kessler.");
|
|
if(1==argc)
|
|
{
|
|
outDebug("USAGE: mcast send|receive address:port {frequency (ms)} {stringdata}");
|
|
outDebug("(ie) mcast send 234.5.6.7:4567 1000 hello");
|
|
return;
|
|
}
|
|
strOp=argv[1];
|
|
strOp.lower();
|
|
strIPAddress=String(argv[2]).betweenString(0,':');
|
|
strPort=String(argv[2]).betweenString(':',0);
|
|
if(5==argc)strData=argv[4];
|
|
else strData="hello world";
|
|
if(argc>=4)strFrequency=argv[3];
|
|
message.size(strData.length()+1);
|
|
::memset(&message[0],0,message.size());
|
|
::strcpy((char*)&message[0],strData.str());
|
|
outDebug(String("mode=")+strOp);
|
|
outDebug(String("address=")+strIPAddress);
|
|
outDebug(String("port=")+strPort);
|
|
if(strOp=="send")mcastsnd(strPort.toInt(),strIPAddress,message,strFrequency.toInt());
|
|
else if(strOp=="receive")mcastrcv(strPort.toInt(),strIPAddress);
|
|
else outDebug("USAGE: mcast send|receive address:port");
|
|
}
|
|
|
|
void mcastrcv(int destPort,String rcvIPAddress,int ttl)
|
|
{
|
|
WSASystem wsaSystem;
|
|
SocketAddress socketAddressLocal;
|
|
SocketAddress socketAddressTo;
|
|
SocketAddress socketAddressFrom;
|
|
IPMReq ipMCast;
|
|
Socket socket;
|
|
|
|
outDebug("Socket create.");
|
|
if(!socket.create(Socket::DomainInternet,Socket::SocketDGram,Socket::ProtocolNone))
|
|
{
|
|
outDebug("Socket creation failed.");
|
|
return;
|
|
}
|
|
if(!socket.reuseAddress(true))
|
|
{
|
|
outDebug("Error setting option REUSEADDR.");
|
|
socket.destroy();
|
|
return;
|
|
}
|
|
outDebug("Socket created.");
|
|
socketAddressLocal.family(AF_INET);
|
|
socketAddressLocal.internetAddress(InternetAddress());
|
|
socketAddressLocal.port(htons(destPort));
|
|
outDebug(String("Socket bind to ")+socketAddressLocal.toString());
|
|
if(!socket.bind(socketAddressLocal))
|
|
{
|
|
outDebug("Bind failed.");
|
|
socket.destroy();
|
|
return;
|
|
}
|
|
outDebug("Socket is bound.");
|
|
if(!socket.setMulticastTTL(ttl))
|
|
{
|
|
outDebug("[Error setting option SET_MULTICAST_TTL.]");
|
|
socket.destroy();
|
|
return;
|
|
}
|
|
ipMCast.multicastAddress(InternetAddress(rcvIPAddress));
|
|
ipMCast.localAddress(InternetAddress());
|
|
outDebug(String("Add membership ")+ipMCast.toString());
|
|
if(!socket.addMembership(ipMCast))
|
|
{
|
|
int error=WSAGetLastError();
|
|
outDebug(String("[Error setting option ADDMEMBERSHIP.] Code=")+String().fromInt(error));
|
|
socket.destroy();
|
|
return;
|
|
}
|
|
outDebug(String("Joined ")+InternetAddress(rcvIPAddress).toString());
|
|
if(!socket.setMulticastLoopback(false))
|
|
{
|
|
int error=WSAGetLastError();
|
|
outDebug(String("[Error setting option MULTICASTLOOPBACK.] Code=")+String().fromInt(error));
|
|
}
|
|
outDebug(String("Loopback is disabled."));
|
|
outDebug("Listening for messages...");
|
|
while(true)
|
|
{
|
|
char buffer[1024];
|
|
INETSocketAddress from;
|
|
if(!socket.receiveFrom(buffer,sizeof(buffer),0,from))
|
|
{
|
|
outDebug("Receive Failed.");
|
|
socket.destroy();
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
SystemTime sysTime;
|
|
outDebug(String("[")+sysTime.toString()+String("]")+String("Received from [")+from.toString()+String("] \"")+String(buffer)+String("\""));
|
|
}
|
|
}
|
|
socket.destroy();
|
|
}
|
|
|
|
void mcastsnd(int destPort,String destIPAddress,Array<BYTE> &message,int frequency,int ttl)
|
|
{
|
|
WSASystem wsaSystem;
|
|
SocketAddress socketAddressLocal;
|
|
Socket socket;
|
|
|
|
if(!socket.create(Socket::DomainInternet,Socket::SocketDGram,Socket::ProtocolNone))
|
|
{
|
|
outDebug("[Socket creation failed]");
|
|
return;
|
|
}
|
|
if(!socket.reuseAddress(true))
|
|
{
|
|
outDebug("[Error setting option REUSEADDR.]");
|
|
socket.destroy();
|
|
return;
|
|
}
|
|
outDebug("Socket created.");
|
|
socketAddressLocal.family(AF_INET);
|
|
socketAddressLocal.internetAddress(InternetAddress());
|
|
socketAddressLocal.port(htons(0));
|
|
if(!socket.bind(socketAddressLocal))
|
|
{
|
|
outDebug("Bind failed.");
|
|
socket.destroy();
|
|
return;
|
|
}
|
|
outDebug("Socket is bound.");
|
|
if(!socket.setMulticastTTL(ttl))
|
|
{
|
|
outDebug("[Error setting option SET_MULTICAST_TTL.]");
|
|
socket.destroy();
|
|
return;
|
|
}
|
|
INETSocketAddress inetSocketAddress;
|
|
inetSocketAddress.family(AF_INET);
|
|
inetSocketAddress.port(destPort);
|
|
inetSocketAddress.internetAddress(InternetAddress(destIPAddress));
|
|
while(true)
|
|
{
|
|
if(!socket.sendTo((void*)&message[0],message.size(),inetSocketAddress))
|
|
{
|
|
outDebug("Send Failed.");
|
|
socket.destroy();
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
SystemTime sysTime;
|
|
outDebug(sysTime.toString()+"Data sent.");
|
|
}
|
|
::Sleep(frequency);
|
|
}
|
|
socket.destroy();
|
|
}
|
|
|
|
void outDebug(const String &string)
|
|
{
|
|
String outString(string+String("\n"));
|
|
cout << ((String&)string).str() << endl;
|
|
::OutputDebugString(outString.str());
|
|
}
|