1 package org.apache.commons.jcs3.utils.discovery;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.net.DatagramPacket;
25 import java.net.InetAddress;
26 import java.net.MulticastSocket;
27 import java.net.NetworkInterface;
28 import java.util.ArrayList;
29
30 import org.apache.commons.jcs3.engine.CacheInfo;
31 import org.apache.commons.jcs3.engine.behavior.IElementSerializer;
32 import org.apache.commons.jcs3.log.Log;
33 import org.apache.commons.jcs3.log.LogManager;
34 import org.apache.commons.jcs3.utils.discovery.UDPDiscoveryMessage.BroadcastType;
35 import org.apache.commons.jcs3.utils.net.HostNameUtil;
36 import org.apache.commons.jcs3.utils.serialization.StandardSerializer;
37
38
39
40
41 public class UDPDiscoverySender implements AutoCloseable
42 {
43
44 private static final Log log = LogManager.getLog( UDPDiscoverySender.class );
45
46
47 private final MulticastSocket localSocket;
48
49
50 private final InetAddress multicastAddress;
51
52
53 private final int multicastPort;
54
55
56 private final IElementSerializer serializer;
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 @Deprecated
72 public UDPDiscoverySender( final String host, final int port, final int udpTTL )
73 throws IOException
74 {
75 this(null, host, port, udpTTL, new StandardSerializer());
76 }
77
78
79
80
81
82
83
84
85
86
87
88
89
90 public UDPDiscoverySender(final UDPDiscoveryAttributes udpDiscoveryAttributes, final IElementSerializer serializer)
91 throws IOException
92 {
93 this(udpDiscoveryAttributes.getUdpDiscoveryInterface(),
94 udpDiscoveryAttributes.getUdpDiscoveryAddr(),
95 udpDiscoveryAttributes.getUdpDiscoveryPort(),
96 udpDiscoveryAttributes.getUdpTTL(),
97 serializer);
98 }
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 public UDPDiscoverySender(final String mcastInterface, final String host,
116 final int port, final int udpTTL, IElementSerializer serializer)
117 throws IOException
118 {
119 try
120 {
121 log.debug( "Constructing socket for sender on port [{0}]", port );
122 localSocket = new MulticastSocket( port );
123
124 if (udpTTL > 0)
125 {
126 log.debug( "Setting datagram TTL to [{0}]", udpTTL );
127 localSocket.setTimeToLive(udpTTL);
128 }
129
130
131 multicastAddress = InetAddress.getByName( host );
132
133
134 NetworkInterface multicastInterface = null;
135 if (mcastInterface != null)
136 {
137 multicastInterface = NetworkInterface.getByName(mcastInterface);
138 }
139 else
140 {
141 multicastInterface = HostNameUtil.getMulticastNetworkInterface();
142 }
143 if (multicastInterface != null)
144 {
145 log.info("Sending multicast via network interface {0}",
146 multicastInterface::getDisplayName);
147 localSocket.setNetworkInterface(multicastInterface);
148 }
149 }
150 catch ( final IOException e )
151 {
152 log.error( "Could not bind to multicast address [{0}]", host, e );
153 throw e;
154 }
155
156 this.multicastPort = port;
157 this.serializer = serializer;
158 }
159
160
161
162
163 @Override
164 public void close()
165 {
166 if ( this.localSocket != null && !this.localSocket.isClosed() )
167 {
168 this.localSocket.close();
169 }
170 }
171
172
173
174
175
176
177
178 public void send( final UDPDiscoveryMessage message )
179 throws IOException
180 {
181 if ( this.localSocket == null )
182 {
183 throw new IOException( "Socket is null, cannot send message." );
184 }
185
186 if ( this.localSocket.isClosed() )
187 {
188 throw new IOException( "Socket is closed, cannot send message." );
189 }
190
191 log.debug( "sending UDPDiscoveryMessage, address [{0}], port [{1}], "
192 + "message = {2}", multicastAddress, multicastPort, message );
193
194 final byte[] bytes = serializer.serialize( message );
195
196
197 final DatagramPacket packet = new DatagramPacket( bytes, bytes.length, multicastAddress, multicastPort );
198
199 log.debug( "Sending DatagramPacket with {0} bytes to {1}:{2}",
200 bytes.length, multicastAddress, multicastPort );
201
202 localSocket.send( packet );
203 }
204
205
206
207
208
209
210
211 public void requestBroadcast()
212 throws IOException
213 {
214 log.debug( "sending requestBroadcast" );
215
216 final UDPDiscoveryMessage message = new UDPDiscoveryMessage();
217 message.setHost(multicastAddress.getHostAddress());
218 message.setPort(multicastPort);
219 message.setRequesterId( CacheInfo.listenerId );
220 message.setMessageType( BroadcastType.REQUEST );
221 send( message );
222 }
223
224
225
226
227
228
229
230
231
232
233 public void passiveBroadcast( final String host, final int port, final ArrayList<String> cacheNames )
234 throws IOException
235 {
236 passiveBroadcast( host, port, cacheNames, CacheInfo.listenerId );
237 }
238
239
240
241
242
243
244
245
246
247
248 protected void passiveBroadcast( final String host, final int port, final ArrayList<String> cacheNames, final long listenerId )
249 throws IOException
250 {
251 log.debug( "sending passiveBroadcast" );
252
253 final UDPDiscoveryMessage message = new UDPDiscoveryMessage();
254 message.setHost( host );
255 message.setPort( port );
256 message.setCacheNames( cacheNames );
257 message.setRequesterId( listenerId );
258 message.setMessageType( BroadcastType.PASSIVE );
259 send( message );
260 }
261
262
263
264
265
266
267
268
269
270
271
272 public void removeBroadcast( final String host, final int port, final ArrayList<String> cacheNames )
273 throws IOException
274 {
275 removeBroadcast( host, port, cacheNames, CacheInfo.listenerId );
276 }
277
278
279
280
281
282
283
284
285
286
287 protected void removeBroadcast( final String host, final int port, final ArrayList<String> cacheNames, final long listenerId )
288 throws IOException
289 {
290 log.debug( "sending removeBroadcast" );
291
292 final UDPDiscoveryMessage message = new UDPDiscoveryMessage();
293 message.setHost( host );
294 message.setPort( port );
295 message.setCacheNames( cacheNames );
296 message.setRequesterId( listenerId );
297 message.setMessageType( BroadcastType.REMOVE );
298 send( message );
299 }
300 }
301
302
303
304
305
306
307 @Deprecated
308 class MyByteArrayOutputStream
309 extends ByteArrayOutputStream
310 {
311
312
313
314
315 public byte[] getBytes()
316 {
317 return buf;
318 }
319 }