
org.globus.net.ServerSocketFactory Maven / Gradle / Ivy
/*
* Copyright 1999-2010 University of Chicago
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
*
* See the License for the specific language governing permissions and limitations under the License.
*/
package org.globus.net;
import java.net.ServerSocket;
import java.net.InetAddress;
import java.io.IOException;
/**
* This factory allows for creating regular server sockets.
* If the tcp.port.range system property is set it will create
* server sockets within the specified port range (if the port
* number is set to 0).
*/
public class ServerSocketFactory {
private static ServerSocketFactory defaultFactory = null;
private PortRange portRange = null;
protected ServerSocketFactory() {
this.portRange = PortRange.getTcpInstance();
}
/**
* Returns the default instance of this class.
*
* @return ServerSocketFactory instance of this class.
*/
public static synchronized ServerSocketFactory getDefault() {
if (defaultFactory == null) {
defaultFactory = new ServerSocketFactory();
}
return defaultFactory;
}
/**
* Creates a server socket on a specified port. A port of
* 0
creates a socket on any free port or if the
* tcp.port.range system property is set it creates a socket
* within the specified port range.
*
* The maximum queue length for incoming connection indications (a
* request to connect) is set to 50
. If a connection
* indication arrives when the queue is full, the connection is refused.
*
* @param port the port number, or 0
to use any
* free port or if the tcp.port.range property set
* to use any available port within the specified port
* range.
* @exception IOException if an I/O error occurs when opening the socket.
*/
public ServerSocket createServerSocket(int port)
throws IOException {
return createServerSocket(port, 50, null);
}
/**
* Creates a server socket on a specified port. A port of
* 0
creates a socket on any free port or if the
* tcp.port.range system property is set it creates a socket
* within the specified port range.
*
* The maximum queue length for incoming connection indications (a
* request to connect) is set to the backlog
parameter. If
* a connection indication arrives when the queue is full, the
* connection is refused.
*
* @param port the port number, or 0
to use any
* free port or if the tcp.port.range property set
* to use any available port within the specified port
* range.
* @param backlog the maximum length of the queue.
* @exception IOException if an I/O error occurs when opening the socket.
*/
public ServerSocket createServerSocket(int port, int backlog)
throws IOException {
return createServerSocket(port, backlog, null);
}
/**
* Create a server with the specified port, listen backlog, and
* local IP address to bind to. The bindAddr argument
* can be used on a multi-homed host for a ServerSocket that
* will only accept connect requests to one of its addresses.
* If bindAddr is null, it will default accepting
* connections on any/all local addresses.
* The port must be between 0 and 65535, inclusive.
*
* @param port the local TCP port
* @param backlog the listen backlog
* @param bindAddr the local InetAddress the server will bind to
* @exception IOException if an I/O error occurs when opening the socket.
*/
public ServerSocket createServerSocket(int port, int backlog,
InetAddress bindAddr)
throws IOException {
if (this.portRange.isEnabled() && port == 0) {
return createServerSocket(backlog, bindAddr);
} else {
return new ServerSocket(port, backlog, bindAddr);
}
}
/**
* Tries to find first available port within the port range specified.
* If it finds a free port, it first checks if the port is not used
* by any other server. If it is, it keeps looking for a next available
* port. If none found, it throws an exception. If the port is available
* the server instance is returned.
*/
private ServerSocket createServerSocket(int backlog, InetAddress binAddr)
throws IOException {
ServerSocket server = null ;
int port = 0;
while(true) {
port = this.portRange.getFreePort(port);
try {
server = new PrServerSocket(port, backlog, binAddr);
this.portRange.setUsed(port);
return server;
} catch(IOException e) {
// continue on
port++;
}
}
}
class PrServerSocket extends ServerSocket {
public PrServerSocket(int port, int backlog, InetAddress bindAddr)
throws IOException {
super(port, backlog, bindAddr);
}
public void close()
throws IOException {
int port = getLocalPort();
try {
super.close();
} finally {
if (port != -1) {
portRange.free(port);
}
}
}
}
}