View Javadoc

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