1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package java.net;
19
20import java.io.FileDescriptor;
21import java.io.IOException;
22import java.io.InputStream;
23import java.io.OutputStream;
24
25/**
26 * This class is the base of all streaming socket implementation classes.
27 * Streaming sockets are wrapped by two classes, {@code ServerSocket} and
28 * {@code Socket} at the server and client end of a connection. At the server,
29 * there are two types of sockets engaged in communication, the {@code
30 * ServerSocket} on a well known port (referred to as listener) used to
31 * establish a connection and the resulting {@code Socket} (referred to as
32 * host).
33 */
34public abstract class SocketImpl implements SocketOptions {
35
36    /**
37     * The remote address this socket is connected to.
38     */
39    protected InetAddress address;
40
41    /**
42     * The remote port this socket is connected to.
43     */
44    protected int port;
45
46    /**
47     * The file descriptor of this socket.
48     */
49    protected FileDescriptor fd;
50
51    /**
52     * The local port this socket is connected to.
53     */
54    protected int localport;
55
56    /**
57     * Waits for an incoming request and blocks until the connection is opened
58     * on the given socket.
59     *
60     * @param newSocket
61     *            the socket to accept connections on.
62     * @throws IOException
63     *             if an error occurs while accepting a new connection.
64     */
65    protected abstract void accept(SocketImpl newSocket) throws IOException;
66
67    /**
68     * Returns the available number of bytes which are readable from this socket
69     * without blocking.
70     *
71     * @return the number of bytes that may be read without blocking.
72     * @throws IOException
73     *             if an error occurs while reading the number of bytes.
74     */
75    protected abstract int available() throws IOException;
76
77    /**
78     * Binds this socket to the specified local host address and port number.
79     *
80     * @param address
81     *            the local machine address to bind this socket to.
82     * @param port
83     *            the port on the local machine to bind this socket to.
84     * @throws IOException
85     *             if an error occurs while binding this socket.
86     */
87    protected abstract void bind(InetAddress address, int port) throws IOException;
88
89    /**
90     * Closes this socket. This makes later access invalid.
91     *
92     * @throws IOException
93     *             if an error occurs while closing this socket.
94     */
95    protected abstract void close() throws IOException;
96
97    /**
98     * Connects this socket to the specified remote host and port number.
99     *
100     * @param host
101     *            the remote host this socket has to be connected to.
102     * @param port
103     *            the remote port on which this socket has to be connected.
104     * @throws IOException
105     *             if an error occurs while connecting to the remote host.
106     */
107    protected abstract void connect(String host, int port) throws IOException;
108
109    /**
110     * Connects this socket to the specified remote host address and port
111     * number.
112     *
113     * @param address
114     *            the remote host address this socket has to be connected to.
115     * @param port
116     *            the remote port on which this socket has to be connected.
117     * @throws IOException
118     *             if an error occurs while connecting to the remote host.
119     */
120    protected abstract void connect(InetAddress address, int port)
121            throws IOException;
122
123    /**
124     * Creates a new unconnected socket. The argument {@code isStreaming}
125     * defines whether the new socket is a streaming or a datagram socket.
126     *
127     * @param isStreaming
128     *            defines whether the type of the new socket is streaming or
129     *            datagram.
130     * @throws IOException
131     *             if an error occurs while creating the socket.
132     */
133    protected abstract void create(boolean isStreaming) throws IOException;
134
135    /**
136     * Gets the file descriptor of this socket.
137     *
138     * @return the file descriptor of this socket.
139     */
140    protected FileDescriptor getFileDescriptor() {
141        return fd;
142    }
143
144    /**
145     * @hide used by java.nio
146     */
147    public FileDescriptor getFD$() {
148        return fd;
149    }
150
151    /**
152     * Gets the remote address this socket is connected to.
153     *
154     * @return the remote address of this socket.
155     */
156    protected InetAddress getInetAddress() {
157        return address;
158    }
159
160    /**
161     * Gets the input stream of this socket.
162     *
163     * @return the input stream of this socket.
164     * @throws IOException
165     *             if an error occurs while accessing the input stream.
166     */
167    protected abstract InputStream getInputStream() throws IOException;
168
169    /**
170     * Gets the local port number of this socket. The field is initialized to
171     * {@code -1} and upon demand will go to the IP stack to get the bound
172     * value. See the class comment for the context of the local port.
173     *
174     * @return the local port number this socket is bound to.
175     */
176    protected int getLocalPort() {
177        return localport;
178    }
179
180    /**
181     * Gets the output stream of this socket.
182     *
183     * @return the output stream of this socket.
184     * @throws IOException
185     *             if an error occurs while accessing the output stream.
186     */
187    protected abstract OutputStream getOutputStream() throws IOException;
188
189    /**
190     * Gets the remote port number of this socket. This value is not meaningful
191     * when this instance is wrapped by a {@code ServerSocket}.
192     *
193     * @return the remote port this socket is connected to.
194     */
195    protected int getPort() {
196        return port;
197    }
198
199    /**
200     * Listens for connection requests on this streaming socket. Incoming
201     * connection requests are queued up to the limit specified by {@code
202     * backlog}. Additional requests are rejected. This method
203     * may only be invoked on stream sockets.
204     *
205     * @param backlog
206     *            the maximum number of outstanding connection requests.
207     * @throws IOException
208     *             if an error occurs while listening.
209     */
210    protected abstract void listen(int backlog) throws IOException;
211
212    /**
213     * Returns a string containing a concise, human-readable description of the
214     * socket.
215     *
216     * @return the textual representation of this socket.
217     */
218    @Override
219    public String toString() {
220        return "Socket[address=" + getInetAddress() +
221                ",port=" + port + ",localPort=" + getLocalPort() + "]";
222    }
223
224    /**
225     * Closes the input channel of this socket.
226     *
227     * <p>This default implementation always throws an {@link IOException} to
228     * indicate that the subclass should have overridden this method.
229     *
230     * @throws IOException
231     *             always because this method should be overridden.
232     */
233    protected void shutdownInput() throws IOException {
234        throw new IOException("Method has not been implemented");
235    }
236
237    /**
238     * Closes the output channel of this socket.
239     *
240     * <p>This default implementation always throws an {@link IOException} to
241     * indicate that the subclass should have overridden this method.
242     *
243     * @throws IOException
244     *             always because this method should be overridden.
245     */
246    protected void shutdownOutput() throws IOException {
247        throw new IOException("Method has not been implemented");
248    }
249
250    /**
251     * Connects this socket to the remote host address and port number specified
252     * by the {@code SocketAddress} object with the given timeout. This method
253     * will block indefinitely if the timeout is set to zero.
254     *
255     * @param remoteAddr
256     *            the remote host address and port number to connect to.
257     * @param timeout
258     *            the timeout value in milliseconds.
259     * @throws IOException
260     *             if an error occurs while connecting.
261     */
262    protected abstract void connect(SocketAddress remoteAddr, int timeout) throws IOException;
263
264    /**
265     * Returns whether the socket supports urgent data or not. Subclasses should
266     * override this method.
267     *
268     * @return {@code false} because subclasses must override this method.
269     */
270    protected boolean supportsUrgentData() {
271        return false;
272    }
273
274    /**
275     * Sends the single byte of urgent data on the socket.
276     *
277     * @param value
278     *            the byte of urgent data.
279     * @throws IOException
280     *             if an error occurs sending urgent data.
281     */
282    protected abstract void sendUrgentData(int value) throws IOException;
283
284    /**
285     * Sets performance preference for connection time, latency and bandwidth.
286     * Does nothing by default.
287     *
288     * @param connectionTime
289     *            the importance of connect time.
290     * @param latency
291     *            the importance of latency.
292     * @param bandwidth
293     *            the importance of bandwidth.
294     */
295    protected void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
296    }
297
298    /**
299     * Initialize the bind() state.
300     * @hide used in java.nio.
301     */
302    public void onBind(InetAddress localAddress, int localPort) {
303        // Do not add any code to these methods. They are concrete only to preserve API
304        // compatibility.
305    }
306
307    /**
308     * Initialize the connect() state.
309     * @hide used in java.nio.
310     */
311    public void onConnect(InetAddress remoteAddress, int remotePort) {
312        // Do not add any code to these methods. They are concrete only to preserve API
313        // compatibility.
314    }
315
316    /**
317     * Initialize the close() state.
318     * @hide used in java.nio.
319     */
320    public void onClose() {
321        // Do not add any code to these methods. They are concrete only to preserve API
322        // compatibility.
323    }
324}
325