1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.mina.util;
20
21 import java.io.IOException;
22 import java.net.DatagramSocket;
23 import java.net.ServerSocket;
24 import java.util.NoSuchElementException;
25 import java.util.Set;
26 import java.util.TreeSet;
27
28
29 /***
30 * Finds currently available server ports.
31 *
32 * @author The Apache Directory Project
33 * @version $Rev: 210062 $
34 * @see <a href="http://www.iana.org/assignments/port-numbers">IANA.org</a>
35 */
36 public class AvailablePortFinder
37 {
38 /***
39 * The minimum number of server port number.
40 */
41 public static final int MIN_PORT_NUMBER = 1;
42
43 /***
44 * The maximum number of server port number.
45 */
46 public static final int MAX_PORT_NUMBER = 49151;
47
48 /***
49 * Creates a new instance.
50 */
51 private AvailablePortFinder()
52 {
53 }
54
55 /***
56 * Returns the {@link Set} of currently available port numbers
57 * ({@link Integer}). This method is identical to
58 * <code>getAvailablePorts(MIN_PORT_NUMBER, MAX_PORT_NUMBER)</code>.
59 *
60 * WARNING: this can take a very long time.
61 */
62 public static Set getAvailablePorts()
63 {
64 return getAvailablePorts(MIN_PORT_NUMBER, MAX_PORT_NUMBER);
65 }
66
67 /***
68 * Gets the next available port starting at the lowest port number.
69 *
70 * @throws NoSuchElementException if there are no ports available
71 */
72 public static int getNextAvailable()
73 {
74 return getNextAvailable(MIN_PORT_NUMBER);
75 }
76
77 /***
78 * Gets the next available port starting at a port.
79 *
80 * @param fromPort the port to scan for availability
81 * @throws NoSuchElementException if there are no ports available
82 */
83 public static int getNextAvailable(int fromPort)
84 {
85 if ((fromPort < MIN_PORT_NUMBER) || (fromPort > MAX_PORT_NUMBER))
86 {
87 throw new IllegalArgumentException("Invalid start port: "
88 + fromPort);
89 }
90
91 for (int i = fromPort; i <= MAX_PORT_NUMBER; i++)
92 {
93 ServerSocket ss = null;
94 DatagramSocket ds = null;
95 try
96 {
97 ss = new ServerSocket(i);
98 ds = new DatagramSocket(i);
99 return i;
100 }
101 catch (IOException e)
102 {
103 }
104 finally
105 {
106 if (ds != null)
107 {
108 ds.close();
109 }
110
111 if (ss != null)
112 {
113 try
114 {
115 ss.close();
116 }
117 catch (IOException e)
118 {
119
120 }
121 }
122 }
123 }
124
125 throw new NoSuchElementException("Could not find an available port "
126 + "above " + fromPort);
127 }
128
129 /***
130 * Checks to see if a specific port is available.
131 *
132 * @param port the port to check for availability
133 */
134 public static boolean available( int port )
135 {
136 if ( ( port < MIN_PORT_NUMBER) || ( port > MAX_PORT_NUMBER ) )
137 {
138 throw new IllegalArgumentException( "Invalid start port: " + port );
139 }
140
141 ServerSocket s = null;
142 try
143 {
144 s = new ServerSocket( port );
145 return true;
146 }
147 catch ( IOException e )
148 {
149 return false;
150 }
151 finally
152 {
153 if ( s != null )
154 {
155 try
156 {
157 s.close();
158 }
159 catch (IOException e)
160 {
161
162 }
163 }
164 }
165 }
166
167 /***
168 * Returns the {@link Set} of currently avaliable port numbers ({@link Integer})
169 * between the specified port range.
170 *
171 * @throws IllegalArgumentException if port range is not between
172 * {@link #MIN_PORT_NUMBER} and {@link #MAX_PORT_NUMBER} or
173 * <code>fromPort</code> if greater than <code>toPort</code>.
174 */
175 public static Set getAvailablePorts(int fromPort, int toPort)
176 {
177 if (
178 (fromPort < MIN_PORT_NUMBER) || (toPort > MAX_PORT_NUMBER)
179 || (fromPort > toPort))
180 {
181 throw new IllegalArgumentException("Invalid port range: "
182 + fromPort + " ~ " + toPort);
183 }
184
185 Set result = new TreeSet();
186
187 for (int i = fromPort; i <= toPort; i++)
188 {
189 ServerSocket s = null;
190
191 try
192 {
193 s = new ServerSocket(i);
194 result.add(new Integer(i));
195 }
196 catch (IOException e)
197 {
198 }
199 finally
200 {
201 if (s != null)
202 {
203 try
204 {
205 s.close();
206 }
207 catch (IOException e)
208 {
209
210 }
211 }
212 }
213 }
214
215 return result;
216 }
217 }