Files
Work/mcast/mcastrcv.cpp
2024-08-07 09:16:27 -04:00

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());
}