View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.util;
8   
9   import java.io.IOException;
10  import java.io.InterruptedIOException;
11  import java.net.Socket;
12  
13  /**
14   * This class implements a timeout feature on socket connections.
15   */
16  public final class TimedSocket
17  {
18      private static final int WATCHDOG_FREQUENCY = 100;
19  
20      private TimedSocket()
21      {
22          // utility class only
23      }
24  
25      /**
26       * Creates a socket and waits until the given timeout is reached.
27       * 
28       * @param host
29       * @param port
30       * @param timeout in milliseconds
31       * @return Connected socket or <code>null</code>.
32       * @throws InterruptedIOException
33       * @throws IOException
34       */
35      public static Socket createSocket(String host, int port, int timeout) throws IOException
36      {
37          SocketConnector connector = new SocketConnector(host, port);
38          connector.start();
39  
40          int timer = 0;
41  
42          while (!connector.isConnected())
43          {
44              if (connector.hasException())
45              {
46                  throw (connector.getException());
47              }
48  
49              try
50              {
51                  Thread.sleep(WATCHDOG_FREQUENCY);
52              }
53              catch (InterruptedException unexpectedInterruption)
54              {
55                  throw new InterruptedIOException("Connection interruption: " + unexpectedInterruption.getMessage());
56              }
57  
58              timer += WATCHDOG_FREQUENCY;
59  
60              if (timer >= timeout)
61              {
62                  throw new InterruptedIOException("Connection timeout on " + host + ":" + port + " after " + timer + " milliseconds");
63              }
64          }
65  
66          return connector.getSocket();
67      }
68  
69      static class SocketConnector extends Thread
70      {
71          private volatile Socket connectedSocket;
72          private String host;
73          private int port;
74          private IOException exception;
75  
76          public SocketConnector(String host, int port)
77          {
78              this.host = host;
79              this.port = port;
80          }
81  
82          public void run()
83          {
84              try
85              {
86                  connectedSocket = new Socket(host, port);
87              }
88              catch (IOException ioe)
89              {
90                  exception = ioe;
91              }
92          }
93  
94          public boolean isConnected()
95          {
96              return connectedSocket != null;
97          }
98  
99          public boolean hasException()
100         {
101             return exception != null;
102         }
103 
104         public Socket getSocket()
105         {
106             return connectedSocket;
107         }
108 
109         public IOException getException()
110         {
111             return exception;
112         }
113     }
114 }