source: greenstone3/trunk/src/java/org/greenstone/server/PortFinder.java@ 19437

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

Related to previous 2 commits: one info output line commented out.

File size: 4.2 KB
Line 
1package org.greenstone.server;
2
3/** Verbatim copy of what's in GLI's org.greenstone.gatherer.util */
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 public PortFinder() {
28 this( PORTS_RESERVED+1, (MAX_PORT - PORTS_RESERVED) );
29 }
30
31 public PortFinder(int base, int blocksize) {
32 PORT_BASE = base;
33 PORT_BLOCK_SIZE = blocksize;
34
35 nextFreePort = PORT_BASE;
36 }
37
38 /** Circular buffer. Modifies the value of nextFreePort (the buffer index). */
39 private void incrementNextFreePort() {
40 int offset = nextFreePort - PORT_BASE;
41 offset = (offset + 1) % PORT_BLOCK_SIZE;
42 nextFreePort = PORT_BASE + offset;
43 }
44
45 /** Finds the first available port in the range specified during Constructor call.
46 * @return the number of an available port.
47 */
48 public int findPortInRange(boolean verbose) throws Exception {
49 try {
50 boolean foundFreePort = false;
51 for(int i = 0; i < PORT_BLOCK_SIZE; i++) {
52
53 if(isPortAvailable(nextFreePort, verbose)) {
54 foundFreePort = true;
55 break;
56
57 } else {
58 incrementNextFreePort();
59 }
60 }
61
62 if(foundFreePort) {
63 // Free port number currently found becomes the port number of the socket
64 // that will be used
65 this.port = nextFreePort;
66 incrementNextFreePort();
67
68 } else {
69 throw new Exception("Cannot find an available port in the range "
70 + PORT_BASE + "-" + (PORT_BASE+PORT_BLOCK_SIZE));
71 }
72
73 } catch(IOException e) {
74 System.err.println("Error when trying to find an available port. In PortFinder.findPort() " + e);
75 }
76 return port;
77 }
78
79 /** @return true if the portnumber is in the valid range. */
80 public static boolean isValidPortNumber(int portNum) {
81 return (portNum >= 0 && portNum <= MAX_PORT);
82 }
83
84 /** @return true if the portnumber is in the useable range. */
85 public static boolean isAssignablePortNumber(int portNum) {
86 return (portNum > PORTS_RESERVED && portNum <= MAX_PORT);
87 }
88
89 /** Finds an available port.
90 * @return the number of an available port.
91 */
92 public static int findAnyFreePort() throws Exception {
93 ServerSocket tmpSocket = null;
94 int portNumber = -1;
95 try {
96 // Creates a server socket, bound to the specified port.
97 // A port of 0 creates a socket on any free port.
98 tmpSocket = new ServerSocket(0);
99 portNumber = tmpSocket.getLocalPort();
100 tmpSocket.close();
101 } catch(Exception e) {
102 System.err.println("Unable to find a free port or close it. Got Exception: " + e);
103 tmpSocket = null;
104 }
105 return portNumber;
106 }
107
108 /** @return true if the portnum is available for use */
109 public static boolean isPortAvailable(int portnum, boolean verbose) {
110 ServerSocket tmpSocket = null;
111 try {
112 tmpSocket = new ServerSocket(portnum);
113 tmpSocket.close();
114 //if(verbose) {
115 //System.err.println("Port " + portnum + " not yet in use.");
116 //}
117 return true;
118
119 } catch(BindException ex){
120 // "Signals that an error occurred while attempting to bind a
121 // socket to a local address and port. Typically, the port is
122 // in use, or the requested local address could not be assigned."
123 if(verbose) {
124 System.err.println("Port " + portnum + " already in use or can't be assigned.");
125 }
126 tmpSocket = null;
127 return false;
128 } catch(Exception ex) {
129 // Some other problem creating or closing the server socket
130 System.err.println("Problem creating or closing server socket at port " + portnum);
131 tmpSocket = null;
132 return false;
133 }
134 }
135}
Note: See TracBrowser for help on using the repository browser.