1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
// IvyWatcher.cpp : implementation file
//
#include "stdafx.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)
{
int err;
int version;
char buffer[256];
string remotehost;
UINT remoteport;
UINT serviceport;
err = ReceiveFrom( buffer, sizeof(buffer), remotehost, remoteport );
if ( err == SOCKET_ERROR )
{
TRACE("Receive Broadcast error %d\n",GetLastError());
return;
}
buffer[err] ='\0';
err = sscanf(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, 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;
string domain;
UINT port;
// determine domain to use
domain = bus->GetDomain( domainlist );
// first find our UDP port
int 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);
string addr;
char hello[1024];
int len = sprintf( hello, "%d %u\n", VERSION, bus->GetApplicationPort() );
// send broadcast to domain list
while ( !domain.empty() )
{
// find addr up to separator
int 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();
}
|