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

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

Updated several files so that the Server2 code in server.jar interacts with GLI code so that the local GS2 server for Linux works the same way as the GS2 Local Library Server on windows

File size: 4.1 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() throws Exception {
49 try {
50 boolean foundFreePort = false;
51 for(int i = 0; i < PORT_BLOCK_SIZE; i++) {
52
53 if(isPortAvailable(nextFreePort)) {
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 + "\nwhich is necessary for forcibly terminating wget.");
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.