SocketImpl.java revision 221d0ccb4cc23ee0bf0646e9abe471fb48b3a1a8
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; 24import org.apache.harmony.luni.platform.INetworkSystem; 25import org.apache.harmony.luni.platform.Platform; 26 27/** 28 * This class is the base of all streaming socket implementation classes. 29 * Streaming sockets are wrapped by two classes, {@code ServerSocket} and 30 * {@code Socket} at the server and client end of a connection. At the server, 31 * there are two types of sockets engaged in communication, the {@code 32 * ServerSocket} on a well known port (referred to as listener) used to 33 * establish a connection and the resulting {@code Socket} (referred to as 34 * host). 35 */ 36public abstract class SocketImpl implements SocketOptions { 37 38 /** 39 * The remote address this socket is connected to. 40 */ 41 protected InetAddress address; 42 43 /** 44 * The remote port this socket is connected to. 45 */ 46 protected int port; 47 48 /** 49 * The file descriptor of this socket. 50 */ 51 protected FileDescriptor fd; 52 53 /** 54 * The local port this socket is connected to. 55 */ 56 protected int localport; 57 58 INetworkSystem netImpl = Platform.getNetworkSystem(); 59 60 // BEGIN android-removed 61 // int receiveTimeout; 62 // END android-removed 63 64 boolean streaming = true; 65 66 /** 67 * Waits for an incoming request and blocks until the connection is opened 68 * on the given socket. 69 * 70 * @param newSocket 71 * the socket to accept connections on. 72 * @throws IOException 73 * if an error occurs while accepting a new connection. 74 */ 75 protected abstract void accept(SocketImpl newSocket) throws IOException; 76 77 /** 78 * Returns the available number of bytes which are readable from this socket 79 * without blocking. 80 * 81 * @return the number of bytes that may be read without blocking. 82 * @throws IOException 83 * if an error occurs while reading the number of bytes. 84 */ 85 protected abstract int available() throws IOException; 86 87 /** 88 * Binds this socket to the specified local host address and port number. 89 * 90 * @param address 91 * the local machine address to bind this socket to. 92 * @param port 93 * the port on the local machine to bind this socket to. 94 * @throws IOException 95 * if an error occurs while binding this socket. 96 */ 97 protected abstract void bind(InetAddress address, int port) 98 throws IOException; 99 100 /** 101 * Closes this socket. This makes later access invalid. 102 * 103 * @throws IOException 104 * if an error occurs while closing this socket. 105 */ 106 protected abstract void close() throws IOException; 107 108 /** 109 * Connects this socket to the specified remote host and port number. 110 * 111 * @param host 112 * the remote host this socket has to be connected to. 113 * @param port 114 * the remote port on which this socket has to be connected. 115 * @throws IOException 116 * if an error occurs while connecting to the remote host. 117 */ 118 protected abstract void connect(String host, int port) throws IOException; 119 120 /** 121 * Connects this socket to the specified remote host address and port 122 * number. 123 * 124 * @param address 125 * the remote host address this socket has to be connected to. 126 * @param port 127 * the remote port on which this socket has to be connected. 128 * @throws IOException 129 * if an error occurs while connecting to the remote host. 130 */ 131 protected abstract void connect(InetAddress address, int port) 132 throws IOException; 133 134 /** 135 * Creates a new unconnected socket. The argument {@code isStreaming} 136 * defines whether the new socket is a streaming or a datagram socket. 137 * 138 * @param isStreaming 139 * defines whether the type of the new socket is streaming or 140 * datagram. 141 * @throws IOException 142 * if an error occurs while creating the socket. 143 */ 144 protected abstract void create(boolean isStreaming) throws IOException; 145 146 /** 147 * Gets the file descriptor of this socket. 148 * 149 * @return the file descriptor of this socket. 150 */ 151 protected FileDescriptor getFileDescriptor() { 152 return fd; 153 } 154 155 /** 156 * Gets the remote address this socket is connected to. 157 * 158 * @return the remote address of this socket. 159 */ 160 protected InetAddress getInetAddress() { 161 return address; 162 } 163 164 /** 165 * Gets the input stream of this socket. 166 * 167 * @return the input stream of this socket. 168 * @throws IOException 169 * if an error occurs while accessing the input stream. 170 */ 171 protected abstract InputStream getInputStream() throws IOException; 172 173 /** 174 * Gets the local port number of this socket. The field is initialized to 175 * {@code -1} and upon demand will go to the IP stack to get the bound 176 * value. See the class comment for the context of the local port. 177 * 178 * @return the local port number this socket is bound to. 179 */ 180 protected int getLocalPort() { 181 return localport; 182 } 183 184 /** 185 * Gets the value of the given socket option. 186 * 187 * @param optID 188 * the socket option to retrieve. 189 * @return the option value. 190 * @throws SocketException 191 * if an error occurs while accessing the option. 192 */ 193 public abstract Object getOption(int optID) throws SocketException; 194 195 /** 196 * Gets the output stream of this socket. 197 * 198 * @return the output stream of this socket. 199 * @throws IOException 200 * if an error occurs while accessing the output stream. 201 */ 202 protected abstract OutputStream getOutputStream() throws IOException; 203 204 /** 205 * Gets the remote port number of this socket. This value is not meaningful 206 * when this instance is wrapped by a {@code ServerSocket}. 207 * 208 * @return the remote port this socket is connected to. 209 */ 210 protected int getPort() { 211 return port; 212 } 213 214 /** 215 * Listens for connection requests on this streaming socket. Incoming 216 * connection requests are queued up to the limit specified by {@code 217 * backlog}. Additional requests are rejected. The method {@code listen()} 218 * may only be invoked on streaming sockets. 219 * 220 * @param backlog 221 * the maximum number of outstanding connection requests. 222 * @throws IOException 223 * if an error occurs while listening. 224 */ 225 protected abstract void listen(int backlog) throws IOException; 226 227 /** 228 * Sets the value for the specified socket option. 229 * 230 * @param optID 231 * the socket option to be set. 232 * @param val 233 * the option value. 234 * @throws SocketException 235 * if an error occurs while setting the option. 236 */ 237 public abstract void setOption(int optID, Object val) 238 throws SocketException; 239 240 /** 241 * Returns a string containing a concise, human-readable description of the 242 * socket. 243 * 244 * @return the textual representation of this socket. 245 */ 246 @SuppressWarnings("nls") 247 @Override 248 public String toString() { 249 return new StringBuilder(100).append("Socket[addr=").append( 250 getInetAddress()).append(",port=").append(port).append( 251 ",localport=").append(getLocalPort()).append("]").toString(); 252 } 253 254 /** 255 * In the IP stack, write at most {@code count} bytes on the socket 256 * from the {@code buffer}, from the {@code offset}. 257 * 258 * @param buffer 259 * the buffer to read into 260 * @param offset 261 * the offset into the buffer 262 * @param count 263 * the number of bytes to write 264 * @return int the actual number of bytes written 265 * @throws IOException 266 * thrown if an error occurs while writing 267 */ 268 int write(byte[] buffer, int offset, int count) throws IOException { 269 if (streaming) { 270 return this.netImpl.write(fd, buffer, offset, count); 271 } else { 272 return this.netImpl.send(fd, buffer, offset, count, port, 0, address); 273 } 274 } 275 276 /** 277 * Closes the input channel of this socket. 278 * <p> 279 * This default implementation always throws an {@link IOException} to 280 * indicate that the subclass should have overridden this method. 281 * 282 * @throws IOException 283 * always because this method should be overridden. 284 */ 285 protected void shutdownInput() throws IOException { 286 throw new IOException("Method has not been implemented"); 287 } 288 289 /** 290 * Closes the output channel of this socket. 291 * <p> 292 * This default implementation always throws an {@link IOException} to 293 * indicate that the subclass should have overridden this method. 294 * 295 * @throws IOException 296 * always because this method should be overridden. 297 */ 298 protected void shutdownOutput() throws IOException { 299 throw new IOException("Method has not been implemented"); 300 } 301 302 /** 303 * Connects this socket to the remote host address and port number specified 304 * by the {@code SocketAddress} object with the given timeout. This method 305 * will block indefinitely if the timeout is set to zero. 306 * 307 * @param remoteAddr 308 * the remote host address and port number to connect to. 309 * @param timeout 310 * the timeout value in milliseconds. 311 * @throws IOException 312 * if an error occurs while connecting. 313 */ 314 protected abstract void connect(SocketAddress remoteAddr, int timeout) 315 throws IOException; 316 317 /** 318 * Returns whether the socket supports urgent data or not. Subclasses should 319 * override this method. 320 * 321 * @return {@code false} because subclasses must override this method. 322 */ 323 protected boolean supportsUrgentData() { 324 return false; 325 } 326 327 /** 328 * Sends the single byte of urgent data on the socket. 329 * 330 * @param value 331 * the byte of urgent data. 332 * @throws IOException 333 * if an error occurs sending urgent data. 334 */ 335 protected abstract void sendUrgentData(int value) throws IOException; 336 337 /** 338 * Sets performance preference for connection time, latency and bandwidth. 339 * Does nothing by default. 340 * 341 * @param connectionTime 342 * the importance of connect time. 343 * @param latency 344 * the importance of latency. 345 * @param bandwidth 346 * the importance of bandwidth. 347 */ 348 protected void setPerformancePreferences(int connectionTime, int latency, 349 int bandwidth) { 350 // Our socket implementation only provide one protocol: TCP/IP, so 351 // we do nothing for this method 352 } 353} 354