// IvyWatcher.cpp : implementation file // #include "IvyStdAfx.h" #include "IvyWatcher.h" #include "IvyApplication.h" ///////////////////////////////////////////////////////////////////////////// // IvyWatcher #define VERSION 3 IvyWatcher::IvyWatcher(Ivy * bus) { this->bus = bus; } IvyWatcher::~IvyWatcher() { } ///////////////////////////////////////////////////////////////////////////// // IvyWatcher member functions void IvyWatcher::OnReceive(int nErrorCode) { size_t err; int version; char buffer[2048]; ivy::string remotehost; UINT remoteport; UINT serviceport; char appid[2048]; char appname[2048]; memset( appid, 0, sizeof( appid ) ); memset( appname, 0, sizeof( appname ) ); err = ReceiveFrom( buffer, sizeof(buffer), remotehost, remoteport ); if ( err == SOCKET_ERROR ) { TRACE("Receive Broadcast error %d\n",this->GetLastError()); return; } if ( err < 255 ) buffer[err] ='\0'; err = sscanf_s(buffer,"%d %u %s %[^\n]",&version, &serviceport,appid, sizeof(appid), appname,sizeof(appname)); if ( err < 2 ) { /* ignore the message */ TRACE(" Bad Supervision message expected 'version port'\n"); return; } if ( version != VERSION ) { /* ignore the message */ TRACE(" Bad Ivy verion number expected %d receive %d from %s:%d\n", VERSION,version, remotehost.c_str(), remoteport); return; } /* check if we received our own message. SHOULD ALSO TEST THE HOST */ if ( strcmp( appid , bus->ApplicationID.c_str()) ==0 ) return; /* check if we receive our own message should test also the host */ if ( serviceport == bus->GetApplicationPort() /*&& remotehost == "localhost"*/) return; TRACE(" Broadcast de %s:%u port %u\n", remotehost.c_str(), remoteport, serviceport ); /* connect to the service and send the regexp */ IvyApplication *newapp = new IvyApplication(bus); // exception to catch newapp->Create(remotehost.c_str(), serviceport, appname ); // delete newapp; // return; bus->AddApplication( newapp ); TRACE(" Connecting to %s:%u\n", remotehost.c_str(), serviceport ); } void IvyWatcher::start(const char *domainlist) { BOOL reuse = TRUE; ivy::string domain; UINT port=0; // determine domain to use domain = bus->GetDomain( domainlist ); // first find our UDP port size_t sep_index = domain.rfind( ':' ); if ( sep_index != -1 ) { port = atoi ( domain.substr( sep_index +1 ).c_str() ); // supress port number from end of domain list domain.erase( sep_index, domain.length() - sep_index ); } // create UDP receiver // catch exception !!! Socket(SOCK_DGRAM); SetSockOpt( SO_REUSEADDR, &reuse, sizeof(BOOL) ); Bind(port); StartListener(); ivy::string addr; char hello[2048]; int len = _snprintf_s( hello, sizeof(hello), sizeof(hello)-1, "%d %u %s %s\n", VERSION, bus->GetApplicationPort(), bus->ApplicationID.c_str(), bus->ApplicationName.c_str() ); // send broadcast to domain list while ( !domain.empty() ) { // find addr up to separator size_t index = domain.find_first_of( ", \t" ); addr = domain.substr( 0, index ); domain.erase( 0, addr.length() +1 ); TRACE("Ivy Broadcasting on %s:%d\n", addr.c_str(), port ); AddMember( addr.c_str() ); SendTo( hello, len, port, addr.c_str() ); } } void IvyWatcher::stop() { Close(); }