1 /* 2 * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.net; 27 28 import java.io.IOException; 29 import java.io.InputStream; 30 import java.io.OutputStream; 31 import java.io.FileDescriptor; 32 import java.util.Set; 33 import sun.net.PlatformSocketImpl; 34 35 /** 36 * The abstract class {@code SocketImpl} is a common superclass 37 * of all classes that actually implement sockets. It is used to 38 * create both client and server sockets. 39 * <p> 40 * A "plain" socket implements these methods exactly as 41 * described, without attempting to go through a firewall or proxy. 42 * 43 * @author unascribed 44 * @since 1.0 45 */ 46 public abstract class SocketImpl implements SocketOptions { 47 48 /** 49 * Creates an instance of platform's SocketImpl 50 */ 51 @SuppressWarnings("unchecked") 52 static <S extends SocketImpl & PlatformSocketImpl> S createPlatformSocketImpl(boolean server) { 53 return (S) new PlainSocketImpl(server); 54 } 55 56 /** 57 * The file descriptor object for this socket. 58 */ 59 protected FileDescriptor fd; 60 61 /** 62 * The IP address of the remote end of this socket. 63 */ 64 protected InetAddress address; 65 66 /** 67 * The port number on the remote host to which this socket is connected. 68 */ 69 protected int port; 70 71 /** 72 * The local port number to which this socket is connected. 73 */ 74 protected int localport; 75 76 /** 77 * Initialize a new instance of this class 78 */ 79 public SocketImpl() { } 80 81 /** 82 * Creates either a stream or a datagram socket. 83 * 84 * @param stream if {@code true}, create a stream socket; 85 * otherwise, create a datagram socket. 86 * @exception IOException if an I/O error occurs while creating the 87 * socket. 88 */ 89 protected abstract void create(boolean stream) throws IOException; 90 91 /** 92 * Connects this socket to the specified port on the named host. 93 * 94 * @param host the name of the remote host. 95 * @param port the port number. 96 * @exception IOException if an I/O error occurs when connecting to the 97 * remote host. 98 */ 99 protected abstract void connect(String host, int port) throws IOException; 100 101 /** 102 * Connects this socket to the specified port number on the specified host. 103 * 104 * @param address the IP address of the remote host. 105 * @param port the port number. 106 * @exception IOException if an I/O error occurs when attempting a 107 * connection. 108 */ 109 protected abstract void connect(InetAddress address, int port) throws IOException; 110 111 /** 112 * Connects this socket to the specified port number on the specified host. 113 * A timeout of zero is interpreted as an infinite timeout. The connection 114 * will then block until established or an error occurs. 115 * 116 * @param address the Socket address of the remote host. 117 * @param timeout the timeout value, in milliseconds, or zero for no timeout. 118 * @exception IOException if an I/O error occurs when attempting a 119 * connection. 120 * @since 1.4 121 */ 122 protected abstract void connect(SocketAddress address, int timeout) throws IOException; 123 124 /** 125 * Binds this socket to the specified local IP address and port number. 126 * 127 * @param host an IP address that belongs to a local interface. 128 * @param port the port number. 129 * @exception IOException if an I/O error occurs when binding this socket. 130 */ 131 protected abstract void bind(InetAddress host, int port) throws IOException; 132 133 /** 134 * Sets the maximum queue length for incoming connection indications 135 * (a request to connect) to the {@code count} argument. If a 136 * connection indication arrives when the queue is full, the 137 * connection is refused. 138 * 139 * @param backlog the maximum length of the queue. 140 * @exception IOException if an I/O error occurs when creating the queue. 141 */ 142 protected abstract void listen(int backlog) throws IOException; 143 144 /** 145 * Accepts a connection. 146 * 147 * @param s the accepted connection. 148 * @exception IOException if an I/O error occurs when accepting the 149 * connection. 150 */ 151 protected abstract void accept(SocketImpl s) throws IOException; 152 153 /** 154 * Returns an input stream for this socket. 155 * 156 * @return a stream for reading from this socket. 157 * @exception IOException if an I/O error occurs when creating the 158 * input stream. 159 */ 160 protected abstract InputStream getInputStream() throws IOException; 161 162 /** 163 * Returns an output stream for this socket. 164 * 165 * @return an output stream for writing to this socket. 166 * @exception IOException if an I/O error occurs when creating the 167 * output stream. 168 */ 169 protected abstract OutputStream getOutputStream() throws IOException; 170 171 /** 172 * Returns the number of bytes that can be read from this socket 173 * without blocking. 174 * 175 * @return the number of bytes that can be read from this socket 176 * without blocking. 177 * @exception IOException if an I/O error occurs when determining the 178 * number of bytes available. 179 */ 180 protected abstract int available() throws IOException; 181 182 /** 183 * Closes this socket. 184 * 185 * @exception IOException if an I/O error occurs when closing this socket. 186 */ 187 protected abstract void close() throws IOException; 188 189 /** 190 * Closes this socket, ignoring any IOException that is thrown by close. 191 */ 192 void closeQuietly() { 193 try { 194 close(); 195 } catch (IOException ignore) { } 196 } 197 198 /** 199 * Places the input stream for this socket at "end of stream". 200 * Any data sent to this socket is acknowledged and then 201 * silently discarded. 202 * 203 * If you read from a socket input stream after invoking this method on the 204 * socket, the stream's {@code available} method will return 0, and its 205 * {@code read} methods will return {@code -1} (end of stream). 206 * 207 * @exception IOException if an I/O error occurs when shutting down this 208 * socket. 209 * @see java.net.Socket#shutdownOutput() 210 * @see java.net.Socket#close() 211 * @see java.net.Socket#setSoLinger(boolean, int) 212 * @since 1.3 213 */ 214 protected void shutdownInput() throws IOException { 215 throw new IOException("Method not implemented!"); 216 } 217 218 /** 219 * Disables the output stream for this socket. 220 * For a TCP socket, any previously written data will be sent 221 * followed by TCP's normal connection termination sequence. 222 * 223 * If you write to a socket output stream after invoking 224 * shutdownOutput() on the socket, the stream will throw 225 * an IOException. 226 * 227 * @exception IOException if an I/O error occurs when shutting down this 228 * socket. 229 * @see java.net.Socket#shutdownInput() 230 * @see java.net.Socket#close() 231 * @see java.net.Socket#setSoLinger(boolean, int) 232 * @since 1.3 233 */ 234 protected void shutdownOutput() throws IOException { 235 throw new IOException("Method not implemented!"); 236 } 237 238 /** 239 * Returns the value of this socket's {@code fd} field. 240 * 241 * @return the value of this socket's {@code fd} field. 242 * @see java.net.SocketImpl#fd 243 */ 244 protected FileDescriptor getFileDescriptor() { 245 return fd; 246 } 247 248 /** 249 * Returns the value of this socket's {@code address} field. 250 * 251 * @return the value of this socket's {@code address} field. 252 * @see java.net.SocketImpl#address 253 */ 254 protected InetAddress getInetAddress() { 255 return address; 256 } 257 258 /** 259 * Returns the value of this socket's {@code port} field. 260 * 261 * @return the value of this socket's {@code port} field. 262 * @see java.net.SocketImpl#port 263 */ 264 protected int getPort() { 265 return port; 266 } 267 268 /** 269 * Returns whether or not this SocketImpl supports sending 270 * urgent data. By default, false is returned 271 * unless the method is overridden in a sub-class 272 * 273 * @return true if urgent data supported 274 * @see java.net.SocketImpl#address 275 * @since 1.4 276 */ 277 protected boolean supportsUrgentData () { 278 return false; // must be overridden in sub-class 279 } 280 281 /** 282 * Send one byte of urgent data on the socket. 283 * The byte to be sent is the low eight bits of the parameter 284 * @param data The byte of data to send 285 * @exception IOException if there is an error 286 * sending the data. 287 * @since 1.4 288 */ 289 protected abstract void sendUrgentData (int data) throws IOException; 290 291 /** 292 * Returns the value of this socket's {@code localport} field. 293 * 294 * @return the value of this socket's {@code localport} field. 295 * @see java.net.SocketImpl#localport 296 */ 297 protected int getLocalPort() { 298 return localport; 299 } 300 301 /** 302 * Returns the address and port of this socket as a {@code String}. 303 * 304 * @return a string representation of this socket. 305 */ 306 public String toString() { 307 return "Socket[addr=" + getInetAddress() + 308 ",port=" + getPort() + ",localport=" + getLocalPort() + "]"; 309 } 310 311 void reset() { 312 fd = null; 313 address = null; 314 port = 0; 315 localport = 0; 316 } 317 318 /** 319 * Sets performance preferences for this socket. 320 * 321 * <p> Sockets use the TCP/IP protocol by default. Some implementations 322 * may offer alternative protocols which have different performance 323 * characteristics than TCP/IP. This method allows the application to 324 * express its own preferences as to how these tradeoffs should be made 325 * when the implementation chooses from the available protocols. 326 * 327 * <p> Performance preferences are described by three integers 328 * whose values indicate the relative importance of short connection time, 329 * low latency, and high bandwidth. The absolute values of the integers 330 * are irrelevant; in order to choose a protocol the values are simply 331 * compared, with larger values indicating stronger preferences. Negative 332 * values represent a lower priority than positive values. If the 333 * application prefers short connection time over both low latency and high 334 * bandwidth, for example, then it could invoke this method with the values 335 * {@code (1, 0, 0)}. If the application prefers high bandwidth above low 336 * latency, and low latency above short connection time, then it could 337 * invoke this method with the values {@code (0, 1, 2)}. 338 * 339 * By default, this method does nothing, unless it is overridden in 340 * a sub-class. 341 * 342 * @param connectionTime 343 * An {@code int} expressing the relative importance of a short 344 * connection time 345 * 346 * @param latency 347 * An {@code int} expressing the relative importance of low 348 * latency 349 * 350 * @param bandwidth 351 * An {@code int} expressing the relative importance of high 352 * bandwidth 353 * 354 * @since 1.5 355 */ 356 protected void setPerformancePreferences(int connectionTime, 357 int latency, 358 int bandwidth) 359 { 360 /* Not implemented yet */ 361 } 362 363 /** 364 * Called to set a socket option. 365 * 366 * @implSpec 367 * The default implementation of this method throws {@code 368 * UnsupportedOperationException}. Subclasses should override this method 369 * with an appropriate implementation. 370 * 371 * @param <T> The type of the socket option value 372 * @param name The socket option 373 * @param value The value of the socket option. A value of {@code null} 374 * may be valid for some options. 375 * 376 * @throws UnsupportedOperationException if the SocketImpl does not 377 * support the option 378 * @throws IllegalArgumentException if the value is not valid for 379 * the option 380 * @throws IOException if an I/O error occurs, or if the socket is closed 381 * @throws NullPointerException if name is {@code null} 382 * 383 * @since 9 384 */ 385 protected <T> void setOption(SocketOption<T> name, T value) throws IOException { 386 throw new UnsupportedOperationException("'" + name + "' not supported"); 387 } 388 389 /** 390 * Called to get a socket option. 391 * 392 * @implSpec 393 * The default implementation of this method throws {@code 394 * UnsupportedOperationException}. Subclasses should override this method 395 * with an appropriate implementation. 396 * 397 * @param <T> The type of the socket option value 398 * @param name The socket option 399 * @return the value of the named option 400 * 401 * @throws UnsupportedOperationException if the SocketImpl does not 402 * support the option 403 * @throws IOException if an I/O error occurs, or if the socket is closed 404 * @throws NullPointerException if name is {@code null} 405 * 406 * @since 9 407 */ 408 protected <T> T getOption(SocketOption<T> name) throws IOException { 409 throw new UnsupportedOperationException("'" + name + "' not supported"); 410 } 411 412 /** 413 * Attempts to copy socket options from this SocketImpl to a target SocketImpl. 414 * At this time, only the SO_TIMEOUT make sense to copy. 415 */ 416 void copyOptionsTo(SocketImpl target) { 417 try { 418 Object timeout = getOption(SocketOptions.SO_TIMEOUT); 419 if (timeout instanceof Integer) { 420 target.setOption(SocketOptions.SO_TIMEOUT, timeout); 421 } 422 } catch (IOException ignore) { } 423 } 424 425 /** 426 * Returns a set of SocketOptions supported by this impl 427 * and by this impl's socket (Socket or ServerSocket) 428 * 429 * @implSpec 430 * The default implementation of this method returns an empty set. 431 * Subclasses should override this method with an appropriate implementation. 432 * 433 * @return a Set of SocketOptions 434 * 435 * @since 9 436 */ 437 protected Set<SocketOption<?>> supportedOptions() { 438 return Set.of(); 439 } 440 }