SocketImpl.java revision 4eb8ca7f1e5de2d208c5fcee8b11a7e50200cf17
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 boolean streaming = true; 61 62 /** 63 * Waits for an incoming request and blocks until the connection is opened 64 * on the given socket. 65 * 66 * @param newSocket 67 * the socket to accept connections on. 68 * @throws IOException 69 * if an error occurs while accepting a new connection. 70 */ 71 protected abstract void accept(SocketImpl newSocket) throws IOException; 72 73 /** 74 * Returns the available number of bytes which are readable from this socket 75 * without blocking. 76 * 77 * @return the number of bytes that may be read without blocking. 78 * @throws IOException 79 * if an error occurs while reading the number of bytes. 80 */ 81 protected abstract int available() throws IOException; 82 83 /** 84 * Binds this socket to the specified local host address and port number. 85 * 86 * @param address 87 * the local machine address to bind this socket to. 88 * @param port 89 * the port on the local machine to bind this socket to. 90 * @throws IOException 91 * if an error occurs while binding this socket. 92 */ 93 protected abstract void bind(InetAddress address, int port) 94 throws IOException; 95 96 /** 97 * Closes this socket. This makes later access invalid. 98 * 99 * @throws IOException 100 * if an error occurs while closing this socket. 101 */ 102 protected abstract void close() throws IOException; 103 104 /** 105 * Connects this socket to the specified remote host and port number. 106 * 107 * @param host 108 * the remote host this socket has to be connected to. 109 * @param port 110 * the remote port on which this socket has to be connected. 111 * @throws IOException 112 * if an error occurs while connecting to the remote host. 113 */ 114 protected abstract void connect(String host, int port) throws IOException; 115 116 /** 117 * Connects this socket to the specified remote host address and port 118 * number. 119 * 120 * @param address 121 * the remote host address this socket has to be connected to. 122 * @param port 123 * the remote port on which this socket has to be connected. 124 * @throws IOException 125 * if an error occurs while connecting to the remote host. 126 */ 127 protected abstract void connect(InetAddress address, int port) 128 throws IOException; 129 130 /** 131 * Creates a new unconnected socket. The argument {@code isStreaming} 132 * defines whether the new socket is a streaming or a datagram socket. 133 * 134 * @param isStreaming 135 * defines whether the type of the new socket is streaming or 136 * datagram. 137 * @throws IOException 138 * if an error occurs while creating the socket. 139 */ 140 protected abstract void create(boolean isStreaming) throws IOException; 141 142 /** 143 * Gets the file descriptor of this socket. 144 * 145 * @return the file descriptor of this socket. 146 */ 147 protected FileDescriptor getFileDescriptor() { 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. The method {@code listen()} 203 * may only be invoked on streaming 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 @SuppressWarnings("nls") 219 @Override 220 public String toString() { 221 return new StringBuilder(100).append("Socket[addr=").append( 222 getInetAddress()).append(",port=").append(port).append( 223 ",localport=").append(getLocalPort()).append("]").toString(); 224 } 225 226 /** 227 * In the IP stack, write at most {@code count} bytes on the socket 228 * from the {@code buffer}, from the {@code offset}. 229 * 230 * @param buffer 231 * the buffer to read into 232 * @param offset 233 * the offset into the buffer 234 * @param count 235 * the number of bytes to write 236 * @return int the actual number of bytes written 237 * @throws IOException 238 * thrown if an error occurs while writing 239 */ 240 int write(byte[] buffer, int offset, int count) throws IOException { 241 if (streaming) { 242 return this.netImpl.write(fd, buffer, offset, count); 243 } else { 244 return this.netImpl.send(fd, buffer, offset, count, port, address); 245 } 246 } 247 248 /** 249 * Closes the input channel of this socket. 250 * <p> 251 * This default implementation always throws an {@link IOException} to 252 * indicate that the subclass should have overridden this method. 253 * 254 * @throws IOException 255 * always because this method should be overridden. 256 */ 257 protected void shutdownInput() throws IOException { 258 throw new IOException("Method has not been implemented"); 259 } 260 261 /** 262 * Closes the output channel of this socket. 263 * <p> 264 * This default implementation always throws an {@link IOException} to 265 * indicate that the subclass should have overridden this method. 266 * 267 * @throws IOException 268 * always because this method should be overridden. 269 */ 270 protected void shutdownOutput() throws IOException { 271 throw new IOException("Method has not been implemented"); 272 } 273 274 /** 275 * Connects this socket to the remote host address and port number specified 276 * by the {@code SocketAddress} object with the given timeout. This method 277 * will block indefinitely if the timeout is set to zero. 278 * 279 * @param remoteAddr 280 * the remote host address and port number to connect to. 281 * @param timeout 282 * the timeout value in milliseconds. 283 * @throws IOException 284 * if an error occurs while connecting. 285 */ 286 protected abstract void connect(SocketAddress remoteAddr, int timeout) 287 throws IOException; 288 289 /** 290 * Returns whether the socket supports urgent data or not. Subclasses should 291 * override this method. 292 * 293 * @return {@code false} because subclasses must override this method. 294 */ 295 protected boolean supportsUrgentData() { 296 return false; 297 } 298 299 /** 300 * Sends the single byte of urgent data on the socket. 301 * 302 * @param value 303 * the byte of urgent data. 304 * @throws IOException 305 * if an error occurs sending urgent data. 306 */ 307 protected abstract void sendUrgentData(int value) throws IOException; 308 309 /** 310 * Sets performance preference for connection time, latency and bandwidth. 311 * Does nothing by default. 312 * 313 * @param connectionTime 314 * the importance of connect time. 315 * @param latency 316 * the importance of latency. 317 * @param bandwidth 318 * the importance of bandwidth. 319 */ 320 protected void setPerformancePreferences(int connectionTime, int latency, 321 int bandwidth) { 322 // Our socket implementation only provide one protocol: TCP/IP, so 323 // we do nothing for this method 324 } 325} 326