// 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[256]; ivy::string remotehost; UINT remoteport; UINT serviceport; 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",&version, &serviceport); 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 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); // 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[1024]; int len = _snprintf_s( hello, sizeof(hello), sizeof(hello)-1, "%d %u\n", VERSION, bus->GetApplicationPort() ); // 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(); }