001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.net;
019
020import java.io.IOException;
021import java.net.InetAddress;
022import java.net.InetSocketAddress;
023import java.net.Proxy;
024import java.net.ServerSocket;
025import java.net.Socket;
026import java.net.UnknownHostException;
027
028import javax.net.SocketFactory;
029
030/**
031 * DefaultSocketFactory implements the SocketFactory interface by simply wrapping the java.net.Socket and java.net.ServerSocket constructors. It is the default
032 * SocketFactory used by {@link org.apache.commons.net.SocketClient} implementations.
033 *
034 *
035 * @see SocketFactory
036 * @see SocketClient
037 * @see SocketClient#setSocketFactory
038 */
039
040public class DefaultSocketFactory extends SocketFactory {
041    /** The proxy to use when creating new sockets. */
042    private final Proxy connProxy;
043
044    /**
045     * The default constructor.
046     */
047    public DefaultSocketFactory() {
048        this(null);
049    }
050
051    /**
052     * A constructor for sockets with proxy support.
053     *
054     * @param proxy The Proxy to use when creating new Sockets.
055     * @since 3.2
056     */
057    public DefaultSocketFactory(final Proxy proxy) {
058        connProxy = proxy;
059    }
060
061    /**
062     * Creates a ServerSocket bound to a specified port. A port of 0 will create the ServerSocket on a system-determined free port.
063     *
064     * @param port The port on which to listen, or 0 to use any free port.
065     * @return A ServerSocket that will listen on a specified port.
066     * @throws IOException If an I/O error occurs while creating the ServerSocket.
067     */
068    public ServerSocket createServerSocket(final int port) throws IOException {
069        return new ServerSocket(port);
070    }
071
072    /**
073     * Creates a ServerSocket bound to a specified port with a given maximum queue length for incoming connections. A port of 0 will create the ServerSocket on
074     * a system-determined free port.
075     *
076     * @param port    The port on which to listen, or 0 to use any free port.
077     * @param backlog The maximum length of the queue for incoming connections.
078     * @return A ServerSocket that will listen on a specified port.
079     * @throws IOException If an I/O error occurs while creating the ServerSocket.
080     */
081    public ServerSocket createServerSocket(final int port, final int backlog) throws IOException {
082        return new ServerSocket(port, backlog);
083    }
084
085    /**
086     * Creates a ServerSocket bound to a specified port on a given local address with a given maximum queue length for incoming connections. A port of 0 will
087     * create the ServerSocket on a system-determined free port.
088     *
089     * @param port     The port on which to listen, or 0 to use any free port.
090     * @param backlog  The maximum length of the queue for incoming connections.
091     * @param bindAddr The local address to which the ServerSocket should bind.
092     * @return A ServerSocket that will listen on a specified port.
093     * @throws IOException If an I/O error occurs while creating the ServerSocket.
094     */
095    public ServerSocket createServerSocket(final int port, final int backlog, final InetAddress bindAddr) throws IOException {
096        return new ServerSocket(port, backlog, bindAddr);
097    }
098
099    /**
100     * Creates an unconnected Socket.
101     *
102     * @return A new unconnected Socket.
103     * @throws IOException If an I/O error occurs while creating the Socket.
104     * @since 3.2
105     */
106    @Override
107    public Socket createSocket() throws IOException {
108        if (connProxy != null) {
109            return new Socket(connProxy);
110        }
111        return new Socket();
112    }
113
114    /**
115     * Creates a Socket connected to the given host and port.
116     *
117     * @param address The address of the host to connect to.
118     * @param port    The port to connect to.
119     * @return A Socket connected to the given host and port.
120     * @throws IOException If an I/O error occurs while creating the Socket.
121     */
122    @Override
123    public Socket createSocket(final InetAddress address, final int port) throws IOException {
124        if (connProxy != null) {
125            final Socket s = new Socket(connProxy);
126            s.connect(new InetSocketAddress(address, port));
127            return s;
128        }
129        return new Socket(address, port);
130    }
131
132    /**
133     * Creates a Socket connected to the given host and port and originating from the specified local address and port.
134     *
135     * @param address   The address of the host to connect to.
136     * @param port      The port to connect to.
137     * @param localAddr The local address to use.
138     * @param localPort The local port to use.
139     * @return A Socket connected to the given host and port.
140     * @throws IOException If an I/O error occurs while creating the Socket.
141     */
142    @Override
143    public Socket createSocket(final InetAddress address, final int port, final InetAddress localAddr, final int localPort) throws IOException {
144        if (connProxy != null) {
145            final Socket s = new Socket(connProxy);
146            s.bind(new InetSocketAddress(localAddr, localPort));
147            s.connect(new InetSocketAddress(address, port));
148            return s;
149        }
150        return new Socket(address, port, localAddr, localPort);
151    }
152
153    /**
154     * Creates a Socket connected to the given host and port.
155     *
156     * @param host The hostname to connect to.
157     * @param port The port to connect to.
158     * @return A Socket connected to the given host and port.
159     * @throws UnknownHostException If the hostname cannot be resolved.
160     * @throws IOException          If an I/O error occurs while creating the Socket.
161     */
162    @Override
163    public Socket createSocket(final String host, final int port) throws UnknownHostException, IOException {
164        if (connProxy != null) {
165            final Socket s = new Socket(connProxy);
166            s.connect(new InetSocketAddress(host, port));
167            return s;
168        }
169        return new Socket(host, port);
170    }
171
172    /**
173     * Creates a Socket connected to the given host and port and originating from the specified local address and port.
174     *
175     * @param host      The hostname to connect to.
176     * @param port      The port to connect to.
177     * @param localAddr The local address to use.
178     * @param localPort The local port to use.
179     * @return A Socket connected to the given host and port.
180     * @throws UnknownHostException If the hostname cannot be resolved.
181     * @throws IOException          If an I/O error occurs while creating the Socket.
182     */
183    @Override
184    public Socket createSocket(final String host, final int port, final InetAddress localAddr, final int localPort) throws UnknownHostException, IOException {
185        if (connProxy != null) {
186            final Socket s = new Socket(connProxy);
187            s.bind(new InetSocketAddress(localAddr, localPort));
188            s.connect(new InetSocketAddress(host, port));
189            return s;
190        }
191        return new Socket(host, port, localAddr, localPort);
192    }
193}