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