source: gli/trunk/src/org/greenstone/gatherer/util/PortFinder.java@ 18991

Last change on this file since 18991 was 18991, checked in by ak19, 15 years ago

Changed exception message.

File size: 4.1 KB
Line 
1package org.greenstone.gatherer.util;
2
3/** Verbatim copy of what's in GS3's org.greenstone.server */
4
5import java.io.IOException;
6import java.net.ServerSocket;
7import java.net.BindException;
8
9// When needing to use sockets, this class can be used to find an available port
10public class PortFinder {
11
12 // Port numbers range from 0 to 65,535. RESERVED PORTS are below 1025
13 // see http://www.gnu.org/software/hello/manual/libc/Ports.html
14 public static final int MAX_PORT = 65535;
15 public static final int PORTS_RESERVED = 1024;
16
17 // Considering a limited range of ports that will be reused (circular buffer)
18 public final int PORT_BASE;
19 public final int PORT_BLOCK_SIZE;
20
21 // Keep track of what port numbers we have checked for availability
22 private int nextFreePort;
23
24 // The socket port number that we will use
25 private int port = -1;
26
27
28 public PortFinder() {
29 this( PORTS_RESERVED+1, (MAX_PORT - PORTS_RESERVED) );
30 }
31
32 public PortFinder(int base, int blocksize) {
33 PORT_BASE = base;
34 PORT_BLOCK_SIZE = blocksize;
35
36 nextFreePort = PORT_BASE;
37 }
38
39 /** Circular buffer. Modifies the value of nextFreePort (the buffer index). */
40 private void incrementNextFreePort() {
41 int offset = nextFreePort - PORT_BASE;
42 offset = (offset + 1) % PORT_BLOCK_SIZE;
43 nextFreePort = PORT_BASE + offset;
44 }
45
46 /** Finds the first available port in the range specified during Constructor call.
47 * @return the number of an available port.
48 */
49 public int findPortInRange() throws Exception {
50 try {
51 boolean foundFreePort = false;
52 for(int i = 0; i < PORT_BLOCK_SIZE; i++) {
53
54 if(isPortAvailable(nextFreePort)) {
55 foundFreePort = true;
56 break;
57
58 } else {
59 incrementNextFreePort();
60 }
61 }
62
63 if(foundFreePort) {
64 // Free port number currently found becomes the port number of the socket
65 // that will be used
66 this.port = nextFreePort;
67 incrementNextFreePort();
68
69 } else {
70 throw new Exception("Cannot find an available port in the range "
71 + PORT_BASE + "-" + (PORT_BASE+PORT_BLOCK_SIZE));
72 }
73
74 } catch(IOException e) {
75 System.err.println("Error when trying to find an available port. In PortFinder.findPort() " + e);
76 }
77 return port;
78 }
79
80 /** @return true if the portnumber is in the valid range. */
81 public static boolean isValidPortNumber(int portNum) {
82 return (portNum >= 0 && portNum <= MAX_PORT);
83 }
84
85 /** @return true if the portnumber is in the useable range. */
86 public static boolean isAssignablePortNumber(int portNum) {
87 return (portNum > PORTS_RESERVED && portNum <= MAX_PORT);
88 }
89
90 /** Finds an available port.
91 * @return the number of an available port.
92 */
93 public static int findAnyFreePort() throws Exception {
94 ServerSocket tmpSocket = null;
95 int portNumber = -1;
96 try {
97 // Creates a server socket, bound to the specified port.
98 // A port of 0 creates a socket on any free port.
99 tmpSocket = new ServerSocket(0);
100 portNumber = tmpSocket.getLocalPort();
101 tmpSocket.close();
102 } catch(Exception e) {
103 System.err.println("Unable to find a free port or close it. Got Exception: " + e);
104 tmpSocket = null;
105 }
106 return portNumber;
107 }
108
109 /** @return true if the portnum is available for use */
110 public static boolean isPortAvailable(int portnum) {
111 ServerSocket tmpSocket = null;
112 try {
113 tmpSocket = new ServerSocket(portnum);
114 tmpSocket.close();
115 //System.err.println("Port " + portnum + " not yet in use.");
116 return true;
117
118 } catch(BindException ex){
119 // "Signals that an error occurred while attempting to bind a
120 // socket to a local address and port. Typically, the port is
121 // in use, or the requested local address could not be assigned."
122 System.err.println("Port " + portnum + " already in use or can't be assigned.");
123 tmpSocket = null;
124 return false;
125 } catch(Exception ex) {
126 // Some other problem creating or closing the server socket
127 System.err.println("Problem creating or closing server socket at port " + portnum);
128 tmpSocket = null;
129 return false;
130 }
131 }
132}
Note: See TracBrowser for help on using the repository browser.