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