~ubuntu-branches/ubuntu/raring/libjboss-remoting-java/raring

« back to all changes in this revision

Viewing changes to src/main/org/jboss/remoting/transport/multiplex/MultiplexClientInvoker.java

  • Committer: Package Import Robot
  • Author(s): Torsten Werner
  • Date: 2011-09-09 14:01:03 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: package-import@ubuntu.com-20110909140103-hqokx61534tas9rg
Tags: 2.5.3.SP1-1
* Newer but not newest upstream release. Do not build samples.
* Change debian/watch to upstream's svn repo.
* Add patch to fix compile error caused by tomcat update.
  (Closes: #628303)
* Switch to source format 3.0.
* Switch to debhelper level 7.
* Remove useless Depends.
* Update Standards-Version: 3.9.2.
* Update README.source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* JBoss, Home of Professional Open Source
 
3
* Copyright 2005, JBoss Inc., and individual contributors as indicated
 
4
* by the @authors tag. See the copyright.txt in the distribution for a
 
5
* full listing of individual contributors.
 
6
*
 
7
* This is free software; you can redistribute it and/or modify it
 
8
* under the terms of the GNU Lesser General Public License as
 
9
* published by the Free Software Foundation; either version 2.1 of
 
10
* the License, or (at your option) any later version.
 
11
*
 
12
* This software is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
15
* Lesser General Public License for more details.
 
16
*
 
17
* You should have received a copy of the GNU Lesser General Public
 
18
* License along with this software; if not, write to the Free
 
19
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 
20
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 
21
*/
 
22
 
 
23
package org.jboss.remoting.transport.multiplex;
 
24
 
 
25
import org.jboss.logging.Logger;
 
26
import org.jboss.remoting.ConnectionFailedException;
 
27
import org.jboss.remoting.InvokerLocator;
 
28
import org.jboss.remoting.marshal.Marshaller;
 
29
import org.jboss.remoting.marshal.UnMarshaller;
 
30
import org.jboss.remoting.marshal.serializable.SerializableMarshaller;
 
31
import org.jboss.remoting.transport.BidirectionalClientInvoker;
 
32
import org.jboss.remoting.transport.PortUtil;
 
33
import org.jboss.remoting.transport.multiplex.MultiplexServerInvoker.SocketGroupInfo;
 
34
import org.jboss.remoting.transport.multiplex.utility.AddressPair;
 
35
import org.jboss.remoting.transport.socket.ClientSocketWrapper;
 
36
import org.jboss.remoting.transport.socket.SocketClientInvoker;
 
37
 
 
38
import java.io.IOException;
 
39
import java.net.InetAddress;
 
40
import java.net.InetSocketAddress;
 
41
import java.net.Socket;
 
42
import java.util.Map;
 
43
 
 
44
/**
 
45
 * <code>MultiplexClientInvoker</code> is the client side of the Multiplex transport.
 
46
 * For more information, see Remoting documentation on labs.jboss.org.
 
47
 *
 
48
 * @author <a href="mailto:tom.elrod@jboss.com">Tom Elrod</a>
 
49
 * @author <a href="mailto:ron.sigal@jboss.com">Ron Sigal</a>
 
50
 * 
 
51
 * @deprecated As of release 2.4.0 the multiplex transport will no longer be actively supported.
 
52
 */
 
53
public class MultiplexClientInvoker extends SocketClientInvoker implements BidirectionalClientInvoker
 
54
{
 
55
   private static final Logger log = Logger.getLogger(MultiplexClientInvoker.class);
 
56
   private static final boolean isTraceEnabled = log.isTraceEnabled();
 
57
   
 
58
   private InetAddress connectAddress;
 
59
   private String connectHost;
 
60
   private int connectPort;
 
61
   private InetSocketAddress connectSocketAddress;
 
62
   private InetSocketAddress bindSocketAddress;
 
63
   private String socketGroupId;
 
64
   private MultiplexServerInvoker.SocketGroupInfo socketGroupInfo;
 
65
   private AddressPair addressPair;
 
66
   private boolean readyToRun;
 
67
 
 
68
   protected String clientSocketClassName = ClientSocketWrapper.class.getName();
 
69
 
 
70
 
 
71
/**
 
72
 * Create a new <code>MultiplexClientInvoker</code>.
 
73
 *
 
74
 * @param locator
 
75
 */
 
76
   public MultiplexClientInvoker(InvokerLocator locator) throws IOException
 
77
   {
 
78
      super(locator);
 
79
   }
 
80
 
 
81
 
 
82
/**
 
83
 * Create a new <code>MultiplexClientInvoker</code>.
 
84
 *
 
85
 * @param locator
 
86
 */
 
87
   public MultiplexClientInvoker(InvokerLocator locator, Map configuration) throws IOException
 
88
   {
 
89
      super(locator, configuration);
 
90
   }
 
91
 
 
92
 
 
93
   protected void handleConnect() throws ConnectionFailedException
 
94
   {
 
95
      try
 
96
      {
 
97
      log.debug("configuring MultiplexClientInvoker for: " + locator);
 
98
      super.handleConnect();
 
99
 
 
100
      this.connectAddress = InetAddress.getByName(locator.getHost());
 
101
      this.connectHost = connectAddress.getHostName();
 
102
      this.connectPort = locator.getPort();
 
103
      this.connectSocketAddress = new InetSocketAddress(connectAddress, connectPort);
 
104
 
 
105
      if (getSocketFactory() != null)
 
106
         configuration.put(Multiplex.SOCKET_FACTORY, getSocketFactory());
 
107
 
 
108
      Map parameters = configuration;
 
109
 
 
110
      if (parameters != null)
 
111
      {
 
112
         configureSocketGroupParameters(parameters);
 
113
      }
 
114
      }
 
115
      catch (Exception e)
 
116
      {
 
117
         throw new ConnectionFailedException(e.getMessage());
 
118
      }
 
119
   }
 
120
 
 
121
 
 
122
/**
 
123
 * Finishes the start up process, once adequate bind and connect information is
 
124
 * made available.  For more information, see the Multiplex subsystem documentation
 
125
 * at labs.jboss.org.
 
126
 */
 
127
   public void finishStart() throws IOException
 
128
   {
 
129
      if (socketGroupInfo != null &&
 
130
          socketGroupInfo.getBindAddress() != null &&
 
131
          bindSocketAddress == null)
 
132
      {
 
133
         InetAddress bindAddress = socketGroupInfo.getBindAddress();
 
134
         int bindPort = socketGroupInfo.getBindPort();
 
135
         bindSocketAddress = new InetSocketAddress(bindAddress, bindPort);
 
136
      }
 
137
 
 
138
      if (socketGroupInfo != null &&
 
139
          socketGroupInfo.getBindAddress() != null &&
 
140
          addressPair == null)
 
141
      {
 
142
         String bindHost = socketGroupInfo.getBindAddress().getHostName();
 
143
         int bindPort = socketGroupInfo.getBindPort();
 
144
         addressPair = new AddressPair(connectHost, connectPort, bindHost, bindPort);
 
145
      }
 
146
 
 
147
      readyToRun = true;
 
148
   }
 
149
 
 
150
   public InvokerLocator getCallbackLocator(Map metadata)
 
151
   {
 
152
      Socket socket = socketGroupInfo.getPrimingSocket();
 
153
      metadata.put(Multiplex.MULTIPLEX_CONNECT_HOST,
 
154
                   socket.getInetAddress().getHostAddress());
 
155
      metadata.put(Multiplex.MULTIPLEX_CONNECT_PORT,
 
156
                   Integer.toString(socket.getPort()));
 
157
      metadata.put(Multiplex.MULTIPLEX_BIND_HOST,
 
158
            socket.getInetAddress().getHostAddress());
 
159
      metadata.put(Multiplex.MULTIPLEX_BIND_PORT,
 
160
            Integer.toString(socket.getPort()));
 
161
      InvokerLocator locator = new InvokerLocator("multiplex",
 
162
                                                  socket.getLocalAddress().getHostAddress(),
 
163
                                                  socket.getLocalPort(),
 
164
                                                  null,
 
165
                                                  metadata);
 
166
      return locator;
 
167
   }
 
168
 
 
169
/**
 
170
 * @param parameters
 
171
 * @throws IOException
 
172
 */
 
173
   protected void configureSocketGroupParameters(Map parameters) throws IOException
 
174
   {
 
175
      String bindHost;
 
176
      String bindPortString;
 
177
      int bindPort = -1;
 
178
      InetAddress bindAddress = null;
 
179
      socketGroupId = (String) parameters.get(Multiplex.CLIENT_MULTIPLEX_ID);
 
180
      log.debug("socketGroupId: " + socketGroupId);
 
181
 
 
182
      synchronized (MultiplexServerInvoker.SocketGroupInfo.class)
 
183
      {
 
184
         if (socketGroupId != null)
 
185
            socketGroupInfo = (SocketGroupInfo) MultiplexServerInvoker.getSocketGroupMap().get(socketGroupId);
 
186
 
 
187
         if (socketGroupInfo != null && socketGroupInfo.getServerInvoker() != null)
 
188
         {
 
189
            log.debug("client rule 1");
 
190
 
 
191
            // If we get here, it's because a MultiplexServerInvoker created a SocketGroupInfo with matching
 
192
            // group id.  We want to make sure that it didn't get a connect address or connect port different
 
193
            // than the ones passed in through the parameters map.
 
194
            InetAddress socketGroupConnectAddress = socketGroupInfo.getConnectAddress();
 
195
            int socketGroupConnectPort = socketGroupInfo.getConnectPort();
 
196
 
 
197
            if (socketGroupConnectAddress != null && !socketGroupConnectAddress.equals(connectAddress))
 
198
            {
 
199
               String message = "socket group connect address (" + socketGroupConnectAddress +
 
200
                                ") does not match connect address (" + connectAddress + ")";
 
201
               log.error(message);
 
202
               throw new IOException(message);
 
203
            }
 
204
 
 
205
            if (socketGroupConnectPort > 0 && socketGroupConnectPort != connectPort)
 
206
            {
 
207
               String message = "socket group connect port (" + socketGroupConnectPort +
 
208
                                ") does not match connect port (" + connectPort + ")";
 
209
               log.error(message);
 
210
               throw new IOException(message);
 
211
            }
 
212
 
 
213
            bindAddress = socketGroupInfo.getBindAddress();
 
214
            bindPort = socketGroupInfo.getBindPort();
 
215
            bindSocketAddress = new InetSocketAddress(bindAddress, bindPort);
 
216
 
 
217
            if (socketGroupInfo.getPrimingSocket() == null)
 
218
            {
 
219
               String connectHost = connectAddress.getHostName();
 
220
               MultiplexServerInvoker.createPrimingSocket(socketGroupInfo, connectHost, connectPort,
 
221
                                                          bindAddress, bindPort,
 
222
                                                          configuration, timeout);
 
223
            }
 
224
 
 
225
            socketGroupInfo.setConnectAddress(connectAddress);
 
226
            socketGroupInfo.setConnectPort(connectPort);
 
227
            socketGroupInfo.addClientInvoker(this);
 
228
 
 
229
            // We got socketGroupInfo by socketGroupId.  Make sure it is also stored by AddressPair.
 
230
            bindHost = bindAddress.getHostName();
 
231
            addressPair = new AddressPair(connectHost, connectPort, bindHost, bindPort);
 
232
            MultiplexServerInvoker.getAddressPairMap().put(addressPair, socketGroupInfo);
 
233
 
 
234
            MultiplexServerInvoker serverInvoker = socketGroupInfo.getServerInvoker();
 
235
            if (serverInvoker != null)
 
236
               serverInvoker.finishStart();
 
237
 
 
238
            finishStart();
 
239
            return;
 
240
         }
 
241
 
 
242
         bindHost = (String) parameters.get(Multiplex.MULTIPLEX_BIND_HOST);
 
243
         bindPortString = (String) parameters.get(Multiplex.MULTIPLEX_BIND_PORT);
 
244
 
 
245
         if (bindHost != null && bindPortString == null)
 
246
         {
 
247
            bindPortString = "0";
 
248
         }
 
249
 
 
250
         if (bindHost == null && bindPortString != null)
 
251
         {
 
252
            bindHost = "localhost";
 
253
         }
 
254
 
 
255
         if (bindHost != null)
 
256
         {
 
257
            log.debug("client rule 2");
 
258
 
 
259
            try
 
260
            {
 
261
               bindPort = Integer.parseInt(bindPortString);
 
262
            }
 
263
            catch (NumberFormatException e)
 
264
            {
 
265
               throw new IOException("number format error for bindPort: " + bindPortString);
 
266
            }
 
267
 
 
268
            if (bindPort != 0)
 
269
            {
 
270
               bindSocketAddress = new InetSocketAddress(bindHost, bindPort);
 
271
               addressPair = new AddressPair(connectHost, connectPort, bindHost, bindPort);
 
272
               socketGroupInfo = (SocketGroupInfo) MultiplexServerInvoker.getAddressPairMap().get(addressPair);
 
273
            }
 
274
 
 
275
            // If socketGroupInfo exists, it's because it was created, along with a priming socket, by a
 
276
            // MultiplexServerInvoker.  Note that we don't look for a match if the bind port was
 
277
            // anonymous.
 
278
            if (socketGroupInfo != null)
 
279
            {
 
280
               socketGroupInfo.setConnectAddress(connectAddress);
 
281
               socketGroupInfo.setConnectPort(connectPort);
 
282
               socketGroupInfo.addClientInvoker(this);
 
283
 
 
284
               // We got socketGroupInfo by AddressPair.  Make sure it is stored by socketGroupId, if we have one.
 
285
               if (socketGroupId != null)
 
286
               {
 
287
                  String socketGroupSocketGroupId = socketGroupInfo.getSocketGroupId();
 
288
 
 
289
                  if (socketGroupSocketGroupId != null && !socketGroupSocketGroupId.equals(socketGroupId))
 
290
                  {
 
291
                     String message = "socket group multiplexId (" + socketGroupSocketGroupId +
 
292
                                      ") does not match multiplexId (" + socketGroupId + ")";
 
293
                     log.error(message);
 
294
                     throw new IOException(message);
 
295
                  }
 
296
 
 
297
                  if (socketGroupSocketGroupId == null)
 
298
                  {
 
299
                     socketGroupInfo.setSocketGroupId(socketGroupId);
 
300
                     MultiplexServerInvoker.getSocketGroupMap().put(socketGroupId, socketGroupInfo);
 
301
                  }
 
302
               }
 
303
 
 
304
               finishStart();
 
305
               return;
 
306
            }
 
307
 
 
308
            if (bindPort == 0 && socketGroupId == null)
 
309
            {
 
310
               String message = "Can never be found by any MultiplexServerInvoker: " +
 
311
                                "bind port == 0 and socketGroupId == null";
 
312
               log.warn(message);
 
313
            }
 
314
 
 
315
            // Anonymous bind port
 
316
            if (bindPort == 0)
 
317
               bindPort = PortUtil.findFreePort(bindHost);
 
318
 
 
319
            socketGroupInfo = new SocketGroupInfo();
 
320
            socketGroupInfo.setConnectAddress(connectAddress);
 
321
            socketGroupInfo.setConnectPort(connectPort);
 
322
            socketGroupInfo.addClientInvoker(this);
 
323
 
 
324
            // Set bindAddress and bindPort to be able to test for inconsistencies with bind address
 
325
            // and bind port determined by companion MultiplexServerInvoker.
 
326
            bindAddress = InetAddress.getByName(bindHost);
 
327
            socketGroupInfo.setBindAddress(bindAddress);
 
328
            socketGroupInfo.setBindPort(bindPort);
 
329
 
 
330
            String connectHost = connectAddress.getHostName();
 
331
            MultiplexServerInvoker.createPrimingSocket(socketGroupInfo, connectHost, connectPort,
 
332
                                                       bindAddress, bindPort, configuration, timeout);
 
333
            MultiplexServerInvoker.getAddressPairMap().put(addressPair, socketGroupInfo);
 
334
 
 
335
            if (socketGroupId != null)
 
336
            {
 
337
               socketGroupInfo.setSocketGroupId(socketGroupId);
 
338
               MultiplexServerInvoker.getSocketGroupMap().put(socketGroupId, socketGroupInfo);
 
339
            }
 
340
 
 
341
            finishStart();
 
342
            return;
 
343
         }
 
344
 
 
345
         if (socketGroupId != null)
 
346
         {
 
347
            log.debug("client rule 3");
 
348
 
 
349
            if (socketGroupInfo == null)
 
350
            {
 
351
               socketGroupInfo = new SocketGroupInfo();
 
352
               socketGroupInfo.setSocketGroupId(socketGroupId);
 
353
               socketGroupInfo.setConnectAddress(connectAddress);
 
354
               socketGroupInfo.setConnectPort(connectPort);
 
355
               MultiplexServerInvoker.getSocketGroupMap().put(socketGroupId, socketGroupInfo);
 
356
            }
 
357
 
 
358
            socketGroupInfo.addClientInvoker(this);
 
359
            return;
 
360
         }
 
361
 
 
362
         log.debug("client rule 4");
 
363
         String connectHost = connectAddress.getHostName();
 
364
         socketGroupInfo = new SocketGroupInfo();
 
365
         MultiplexServerInvoker.createPrimingSocket(socketGroupInfo, connectHost, connectPort,
 
366
                                                    configuration, timeout);
 
367
         finishStart();
 
368
      }
 
369
   }
 
370
 
 
371
   /**
 
372
    * @param sessionId
 
373
    * @param invocation
 
374
    * @param marshaller
 
375
    * @return
 
376
    * @throws java.io.IOException
 
377
    * @throws org.jboss.remoting.ConnectionFailedException
 
378
    *
 
379
    */
 
380
   protected Object transport(String sessionId, Object invocation, Map metadata, Marshaller marshaller, UnMarshaller unmarshaller)
 
381
   throws IOException, ConnectionFailedException, ClassNotFoundException
 
382
   {
 
383
      log.debug("entering transport()");
 
384
      if (!readyToRun)
 
385
         throw new IOException("connection to server has not been made");
 
386
 
 
387
      return super.transport(sessionId, invocation, metadata, marshaller, unmarshaller);
 
388
   }
 
389
 
 
390
 
 
391
   /**
 
392
    * subclasses must implement this method to provide a hook to disconnect from the remote server, if this applies
 
393
    * to the specific transport. However, in some transport implementations, this may not make must difference since
 
394
    * the connection is not persistent among invocations, such as SOAP.  In these cases, the method should
 
395
    * silently return without any processing.
 
396
    */
 
397
   protected void handleDisconnect()
 
398
   {
 
399
      //TODO: -TME Should this be a no op or need to pool?
 
400
 
 
401
      log.debug("entering handleDisconnect()");
 
402
      super.handleDisconnect();
 
403
 
 
404
      synchronized (MultiplexServerInvoker.SocketGroupInfo.class)
 
405
      {
 
406
         if (socketGroupInfo != null)
 
407
         {
 
408
            socketGroupInfo.removeClientInvoker(this);
 
409
 
 
410
            if (socketGroupInfo.getClientInvokers().isEmpty() && socketGroupInfo.getServerInvoker() == null)
 
411
            {
 
412
               log.debug("invoker group shutting down: " + socketGroupInfo.getSocketGroupId());
 
413
 
 
414
               if (socketGroupInfo.getPrimingSocket() != null)
 
415
               {
 
416
                  log.debug("MultiplexClientInvoker: closing bind priming socket");
 
417
 
 
418
                  VirtualSocket ps = socketGroupInfo.getPrimingSocket();
 
419
                  if (ps != null)
 
420
                  {
 
421
                     try
 
422
                     {
 
423
                        // When the remote virtual MultiplexServerInvoker learns that the
 
424
                        // priming socket has closed, it will close its VirtualServerSocket,
 
425
                        // rendering unshareable the MultiplexingManager that underlies this
 
426
                        // socket group.  We mark it as unshareable immediately so that it will
 
427
                        // not be reused by any other socket group.
 
428
                        ps.getManager().unregisterShareable();
 
429
                        ps.close();
 
430
                     }
 
431
                     catch (IOException e)
 
432
                     {
 
433
                        log.error("Error closing bind priming socket during cleanup upon stopping", e);
 
434
                     }
 
435
                  }
 
436
               }
 
437
 
 
438
               socketGroupId = socketGroupInfo.getSocketGroupId();
 
439
 
 
440
               if (socketGroupId != null)
 
441
               {
 
442
                  MultiplexServerInvoker.getSocketGroupMap().remove(socketGroupId);
 
443
               }
 
444
 
 
445
               // addressPair is set in finishStart().
 
446
               if (addressPair != null)
 
447
               {
 
448
                  MultiplexServerInvoker.getAddressPairMap().remove(addressPair);
 
449
               }
 
450
            }
 
451
 
 
452
            socketGroupInfo = null;  // Prevent from occurring a second time in Finalizer thread.
 
453
         }
 
454
      }
 
455
   }
 
456
 
 
457
 
 
458
/**
 
459
 * @return
 
460
 */
 
461
   protected InetSocketAddress getBindSocketAddress()
 
462
   {
 
463
      return bindSocketAddress;
 
464
   }
 
465
 
 
466
 
 
467
/**
 
468
 * @return
 
469
 */
 
470
   protected InetSocketAddress getConnectSocketAddress()
 
471
   {
 
472
      return connectSocketAddress;
 
473
   }
 
474
 
 
475
 
 
476
   /**
 
477
    * Each implementation of the remote client invoker should have
 
478
    * a default data type that is uses in the case it is not specified
 
479
    * in the invoker locator uri.
 
480
    *
 
481
    * @return
 
482
    */
 
483
   protected String getDefaultDataType()
 
484
   {
 
485
      return SerializableMarshaller.DATATYPE;
 
486
   }
 
487
 
 
488
 
 
489
   protected Socket createSocket(String address, int port, int timeout) throws IOException
 
490
   {
 
491
      log.debug("MultiplexClientInvoker.createSocket()");
 
492
      
 
493
      if (timeout < 0)
 
494
      {
 
495
         timeout = getTimeout();
 
496
         if (timeout < 0)
 
497
            timeout = 0;
 
498
      }
 
499
 
 
500
      // If connection has been broken, try to connect to new server.
 
501
      if (socketGroupInfo != null && socketGroupInfo.getPrimingSocket() != null)
 
502
      {
 
503
         VirtualSocket primingSocket = socketGroupInfo.getPrimingSocket();
 
504
         if (!primingSocket.isFunctional() || primingSocket.hasReceivedDisconnectMessage())
 
505
         {
 
506
            log.info("Current server is inaccessible.  Will try to connect to new server");
 
507
            primingSocket.close();
 
508
 
 
509
            // Get new priming socket.
 
510
            if (bindSocketAddress != null)
 
511
            {
 
512
               InetAddress bindAddress = bindSocketAddress.getAddress();
 
513
               int bindPort = PortUtil.findFreePort(bindSocketAddress.getHostName());
 
514
               socketGroupInfo.setBindPort(bindPort);
 
515
               bindSocketAddress = new InetSocketAddress(bindAddress, bindPort);
 
516
               MultiplexServerInvoker.createPrimingSocket(socketGroupInfo,
 
517
                                                          connectHost, connectPort,
 
518
                                                          bindAddress, bindPort,
 
519
                                                          configuration, timeout);
 
520
            }
 
521
            else
 
522
               MultiplexServerInvoker.createPrimingSocket(socketGroupInfo,
 
523
                                                          connectHost, connectPort,
 
524
                                                          configuration, port);
 
525
 
 
526
            MultiplexServerInvoker serverInvoker = socketGroupInfo.getServerInvoker();
 
527
            if (serverInvoker != null)
 
528
            {
 
529
               try
 
530
               {
 
531
                  // Restart callback server invoker with new server socket.
 
532
                  serverInvoker.stop();
 
533
                  socketGroupInfo.setServerInvoker(null);
 
534
                  serverInvoker.resetLocator(bindSocketAddress.getPort());
 
535
                  serverInvoker.refreshServerSocket();
 
536
                  serverInvoker.setup();
 
537
                  serverInvoker.start();
 
538
               }
 
539
               catch (Exception e)
 
540
               {
 
541
                  log.error(e.getMessage(), e);
 
542
               }
 
543
            }
 
544
 
 
545
            VirtualSocket socket = new VirtualSocket(configuration);
 
546
            for (int i = 0; i < 3; i++)
 
547
            {
 
548
               try
 
549
               {
 
550
                  socket.connect(connectSocketAddress, bindSocketAddress, timeout);
 
551
                  return socket;
 
552
               }
 
553
               catch (Exception e)
 
554
               {
 
555
                  try
 
556
                  {
 
557
                     Thread.sleep(500);
 
558
                  }
 
559
                  catch (InterruptedException e1)
 
560
                  {
 
561
                  }
 
562
               }
 
563
            }
 
564
         }
 
565
      }
 
566
 
 
567
      VirtualSocket socket = new VirtualSocket(configuration);
 
568
      socket.connect(connectSocketAddress, bindSocketAddress, timeout);
 
569
      return socket;
 
570
   }
 
571
}
 
 
b'\\ No newline at end of file'